Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.76/21: Рейтинг темы: голосов - 21, средняя оценка - 4.76
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826

Масштабирование системы при использовании паттерна Singleton

04.01.2017, 10:51. Показов 4525. Ответов 85
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день, как доказать или опровергнуть, что архитектура теряет гибкость и расширяемость при активном использовании паттерна Singleton.
1
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
04.01.2017, 10:51
Ответы с готовыми решениями:

Насчёт шаблонного паттерна SingleTon
Есть код паттерна template<class T> class Singleton { private: static T* ptr; protected: Singleton();

Необходима альтернатива при использовании Proxy паттерна
Здравствуйте, возникла проблема, которую я так и не придумал, как рационально решить. В общем, задача состояла в том, чтобы отследить...

Реализация паттерна Singleton
Добрый день. Необходимо реализовать класс Storage, объект которого будет единственным в программе. Для достижения данной цели было выбрано...

85
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
11.01.2017, 17:57
Студворк — интернет-сервис помощи студентам
GbaLog-,
У вас получается два getProductById, а у меня один
Если завтра третья БД появился, вам придется ещё для всех провайдеров создавать копии, дублировать код
А в том примере что я привел достаточно будет написать адаптер и все
А вам придется написать адаптер + новую реализацию всех кто использует адаптеры
Поправьте если ошибаюсь
0
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
11.01.2017, 18:06
Цитата Сообщение от sys_beginner Посмотреть сообщение
Поправьте если ошибаюсь
Мне придётся написать только адаптер.
Ну и typedef в верхнем регистре для ясности пользователя.
Вам придётся написать адаптер и включить в if или map свою бд.
Цитата Сообщение от sys_beginner Посмотреть сообщение
Если завтра третья БД появился, вам придется ещё для всех провайдеров создавать копии
Что за провайдеры?
Цитата Сообщение от sys_beginner Посмотреть сообщение
+ новую реализацию всех кто использует адаптеры
Что за бред? При написании нового класса старое останется в том же виде, каком и было.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
11.01.2017, 18:10
Цитата Сообщение от GbaLog- Посмотреть сообщение
И пользователь продукт получает, и мы реализацию закрываем.
бинго!
0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
11.01.2017, 19:13
GbaLog-,
Ок, пройдемся по проблемам в данной реализации по отдельности

1. У вас количество getProductById растет с появлением поддержки новых БД, что ведет к дублированию кода
- Это означает, что допустим, клиент потребует после запуска программы добавить ещё и срок годности продукта, вам придется менять это в нескольких точках, количество точек равно количеству getProductById. В реализации которую предложил я - количество изменяемых точек всегда равно 1. Разницу я думаю вы уже почувствовали

2. "Мне придётся написать только адаптер"
- Адаптер это шаблон проектирования, задача которого это объединить разные интерфейсы, решающие одинаковую по смыслу задачу в единый интерфейс. Так же адаптер может предоставлять программисту несколько стандартных вызовов как одно целое, то есть в качестве метода. В вашей реализации адаптеров нет, есть сущности которые предоставляют конкретные данные. Это означает, что при работе с БД вы снова столкнетесь с дублированием кода.

3. Обратим внимание на класс DB.
- Ввиду того, что название этого класса обобщенное можно сделать вывод, что получение/добавление/удаление/обновление всех данных будет происходить через него. Допустим, вам нужно получить список менеджеров из БД. Судя по всему, вы добавите этот метод в класс DB, и в итоге один класс будет содержать методы не связанные друг с другом по смыслу. Менеджеры это отдельная сущность, а товары системы совсем другая.

Цитата Сообщение от GbaLog- Посмотреть сообщение
Что за провайдеры?
Сущности которые предоставляют конкретные данные.
0
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
11.01.2017, 19:54
Цитата Сообщение от sys_beginner Посмотреть сообщение
У вас количество getProductById растет с появлением поддержки новых БД, что ведет к дублированию кода
А у вас всё завязано на методе query, и при добавлении новой БД вам придётся написать ещё один адаптер, который будет так же реализовывать этот метод...
Так что непонятно, к чему вообще о кол-ве методов тут говорить.
Цитата Сообщение от sys_beginner Посмотреть сообщение
допустим, клиент потребует после запуска программы добавить ещё и срок годности продукта, вам придется менять это в нескольких точках
Ничего подобного. Просто добавляем поле срока годности в класс Product.
Цитата Сообщение от sys_beginner Посмотреть сообщение
Разницу я думаю вы уже почувствовали
Пока что чувствую только то, что вы открываете клиенту много информации, а я - нет.
Цитата Сообщение от sys_beginner Посмотреть сообщение
Адаптер это шаблон проектирования, задача которого это объединить разные интерфейсы, решающие одинаковую по смыслу задачу в единый интерфейс. Так же адаптер может предоставлять программисту несколько стандартных вызовов как одно целое, то есть в качестве метода.
Я это знаю, но вы, кажется, не до конца мой псевдокод поняли.
Цитата Сообщение от sys_beginner Посмотреть сообщение
В вашей реализации адаптеров нет
Ок.
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <iostream>
#include <utility>
/////////////////////////////////////////////////////////////////////////////////////////
class IBDType
{
public:
    virtual ~IBDType() = default;
    virtual Product* getProductById(int) = 0;
};
/////////////////////////////////////////////////////////////////////////////////////////
class PostgreSQL : public IBDType
{
public:
    PostgreSQL()
    {
        std::cout << "connected to postgre\n";
    }
    
    virtual Product* getProductById(int) override
    {
        std::cout << "get product from postgre\n";
        //specific for PostgreSQLDataBase operation
        return new Product{/*some args created in progress work*/};
    }
private:
    PostgreSQLDataBase* DB;
};
/////////////////////////////////////////////////////////////////////////////////////////
class MySQL : public IBDType
{
public:
    MySQL()
    {
        std::cout << "connected to mysql\n";
    }
    
    virtual Product* getProductById(int) override
    {
        std::cout << "get product from mysql\n";
        //specific for MySQLDataBase operation
        return new Product{/*some args created in progress work*/};
    }
private:
    MySQLDataBase* DB;
};
/////////////////////////////////////////////////////////////////////////////////////////
typedef PostgreSQL POSTGRESQL;
typedef MySQL MYSQL;
/////////////////////////////////////////////////////////////////////////////////////////
//in singleton
class bd
{
public:
    //...
    template<typename BDType, typename... Args>
    static void connect(Args&&... args)
    {
        if (BDBase == nullptr)
            BDBase = new BDType(std::forward<Args>(args)...);
        else
        {
            delete BDBase;
            BDBase = new BDType(std::forward<Args>(args)...);
        }
    }
    
    static Product* getProductById(int id)
    {
        return BDBase->getProductById(id);
    }
    
    static IBDType* BDBase;
    //...
};
/////////////////////////////////////////////////////////////////////////////////////////
IBDType* bd::BDBase = nullptr;
/////////////////////////////////////////////////////////////////////////////////////////
int main()
{
    bd::connect<POSTGRESQL>();
    Product* p1 = bd::getProductById(1);
    bd::connect<MYSQL>();
    Product* p2 = bd::getProductById(1);
    delete p1;
    delete p2;
}
Обратите внимание на комментарии.

Цитата Сообщение от sys_beginner Посмотреть сообщение
в итоге один класс будет содержать методы не связанные друг с другом по смыслу.
Можно вообще заменить все методы обращения к конкретным бд в метод request, как это сделано у вас с методом query.

Не по теме:

Ладно, что-то я уже плохо соображаю.

0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
11.01.2017, 20:16
Цитата Сообщение от GbaLog- Посмотреть сообщение
А у вас всё завязано на методе query, и при добавлении новой БД вам придётся написать ещё один адаптер, который будет так же реализовывать этот метод...
Да. Но обратите внимание на разницу, есть допустим 50 сущности(продукт, менеджер, машина и т.д), так?
Что проще, написать один query с появлением новой БД или вместо одного query создать 50 новых сущностей с методами getЧто-то(для продукта,менеджера,машины и т.д), которые будут получать данные из новой БД? Это ещё упрощенно. Обычно методов бывает намного больше.

Цитата Сообщение от GbaLog- Посмотреть сообщение
Ничего подобного. Просто добавляем поле срока годности в класс Product.
Ха-ха. А данные в этот продукт(объект) сами по себе же не попадут )) Их так же придется забрать из БД и передавать в объект в каждой реализации getЧтото.

Цитата Сообщение от GbaLog- Посмотреть сообщение
Я это знаю, но вы, кажется, не до конца мой псевдокод поняли.
Судя по всему вы под адаптером подразумеваете классы MySQL и PostgreSQL. Но они не подходят под описание адаптера, у них одинаковый интерфейс ведь так? А адаптер как раз делает все наоборот, объединяет разные интерфейсы в один единый. По коду эти классы работают с сущностью "продукт" и имеют одинаковый интерфейс. Не может адаптер преобразовывать одинаковые интерфейсы в одинаковый интерфейс, в этом просто нет необходимости

Цитата Сообщение от GbaLog- Посмотреть сообщение
Пока что чувствую только то, что вы открываете клиенту много информации, а я - нет.
Не, у меня просто набор адаптеров и один код, который использует эти адаптеры прозрачно. Без дублирования.

Цитата Сообщение от GbaLog- Посмотреть сообщение
Ладно, что-то я уже плохо соображаю.
Заработались видимо Бывает
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
11.01.2017, 20:16
Помогаю со студенческими работами здесь

Может ли потребоваться применение механизма событий при использовании паттерна MVVM?
Паттерн MVVM провозглашён как базовый паттерн для приложений WPF. В паттерне MVVM используется механизм команд. То есть, если...

Настройка системы при использовании SSD
Здравствуйте. Хотелось бы знать, нужно ли настраивать систему при использовании SSD.

Постоянно прохожу проверку CAPTCHA при использовании поисковой системы
Доброго времени суток. Проблема следующая: при поиске в гугле или яндексе эти поисковые системы постоянно запрашивают пройти проверку...

Collections: singleton/singletonList/singletonMap. Что значит слово singleton?
Заметил, что в классе Collections (утилитный класс) имеются методы для оборачивания элемента в set/list/map Все эти методы содержат в...

Установка "лимита" на значение решения системы ОДУ при использовании решателя ode45
Добрый день. Есть такая задачка: при решении системы дифференциальных уравнений, пусть одно из решений имеет величину, условно говоря, с 1...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
86
Ответ Создать тему
Новые блоги и статьи
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка SDL3 и Box2D из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru