Войти
ПрограммированиеФорумОбщее

Синглтон (Singleton) (комментарии) (3 стр)

Страницы: 1 2 3 4 Следующая »
#30
16:48, 31 янв. 2014

IROV..
> Да, и это демотивирует, когда нужно убрать или добавить новый сервис.
Ну может наоборот зато сразу видно какие зависимости нужны?


#31
16:55, 31 янв. 2014

laMer007
> Ну может наоборот зато сразу видно какие зависимости нужны?
Зачем тебе видеть зависимости?

#32
17:21, 31 янв. 2014

IROV..
Чтобы узнать какие нужно предоставить. А то ведь или это передаю я вручную или за меня это делает иок контейнер автоматически.

#33
17:54, 31 янв. 2014

Kartonagnick
> вот вам пример:
>
> os::file config = os::loadConfig("config.xml");

И в каком месте тут синглтоны?

#34
18:03, 31 янв. 2014

laMer007
Я думаю это лучше описать в Мануале к сервису, если он является Черной коробкой, ну или просто по коду если это открыто.
Да и опять же говорю, этим лучше заниматься на уровне Bootstrapper

Вводить в "код конструктора" -это не есть правильно потому что у разной реализации - разный набор зависимых сервисов.
А интерфейс должен быть един.

в любом случае тебе на уровне создания инициализации класса нужно будет писать

IService * service = MyRenderService(logService, fileService);

или

IService * service = MyRenderService(serviceProvider);
service->validateDependencies();

а вообще я буду делать так

будет гдето xml(или даже какойто config.h) где будет перечислен какие сервисы зависят от каких, и какие в какой последовательности создаются и их проперти

#35
18:04, 31 янв. 2014

IROV..
А как вам такой вариант?

struct ServiceProvider1
{
  ServiceProvider1(Service2& service1, Service3& service2, Service3& service3, Service4& service4, Service5& service5):
    service1(service1),
    service2(service2),
    service3(service3),
    service4(service4),
    service5(service5),
 {}

  fun<Service1> service1;//fun - функциональный объект (operator() перегружен), хранящий ссылку на сервис, чтобы не писать кроме членов ещё и две функции - константную и не константную.
  fun<Service2> service2;
  fun<Service3> service3;
  fun<Service4> service4;
  fun<Service5> service5;
};

class Service1
{
public:
  template<class ServiceProvider> 
  Service1(ServiceProvider serviceProvider):
    service2(serviceProvider.service2()),//Ссылки на сервисы получаем.
    service3(serviceProvider.service3()),
    myMember1(serviceProvider),//эти мемберы сами внутри воспользуются провайдерами зависимостей
    myMember2(serviceProvider),
    myMember3(),
    myMember4(myServiceProviderGeter<ServiceProvider>()),//Этому мембору понадобились новые зависимости, часть тех, что хранятся в ServiceProvider, а часть новых среди членов Service1.
    myMember5(myServiceProviderGeter<ServiceProvider>())
    myMember6(myServiceProviderGeter<ServiceProvider>())
  {}
  ...
private:
  template<class BaseServiceProvider>
  struct MyServiceProvider: BaseServiceProvider
    {
       MyServiceProvider(BaseServiceProvider baseServiceProvider, Service6& service6, Service7& service7):
         BaseServiceProvider(baseServiceProvider),
         service6(service6),
         service7(service7)
       {}
       
       fun<Service6> service6;
       fun<Service7> service7;
    };

  template<class BaseServiceProvider> MyServiceProvider<BaseServiceProvider> myServiceProviderGeter(BaseServiceProvider baseServiceProvider) const
  {
    return MyServiceProvider<BaseServiceProvider>(baseServiceProvider, this->myMember2, this->myMember3);
  }
};
...
ServiceProvider1 sp(...);
Servive1 service1(sp);
Service8 service8(sp);
Service9 service9(sp);
...
Теперь куча зависимостей спрятана в общий класс и в случае очень глубокой иерархии и куч объектов на разных уровнях (требующего примерно одинаковых зависимостей или меньше зависимостей) получает практически один параметр. В некоторых случаях будет меньше писанины. Ошибки типизации не переносятся на этап выполнения. Ошибки поиска зависимостей опять же не переносятся на этап исполнения. Интерфейсы можно не выделять, если это важно для приложения ради высокой производительности. То есть ради производительности не используются виртуальные функции, не используется поиск в иок контейнере, используются объекты на стеке или глобальные, используются самый конкретный потомок, а не какой-то его предок. В случае рефакторинга не придется заменять всюду по коду кучу зависимостей во всех параметрах, тк однажды упаковав новый в сервис провайдер сервис - он будет заменен на всех уровнях ниже по иерархии владения во всех экземплярах классов, куда передавали сервис провайдер.
#36
18:05, 31 янв. 2014

Executor
> И в каком месте тут синглтоны?
Наверное os, но я бы сказал что это неймспейс или моностейт.

#37
18:11, 31 янв. 2014

IROV..
> где будет перечислен какие сервисы зависят от каких, и какие в какой последовательности создаются
По идеи зависимости сервисов уже хватит, чтобы вычислить ту последовательность, в какой их создавать и указывать в xml отдельно это не нужно.
Единственное, что можно добавить - это ленивость сервиса. То есть если не указано специально, то сервис не создаётся, пока не потребуется и может не создаться до завершения приложения.

#38
18:19, 31 янв. 2014

laMer007
ServiceProvider - должен иметь виртуальный интерфейс, по этому не совсем корректно.

  Service1(ServiceProvider serviceProvider):
    service2(serviceProvider.service2()),//Ссылки на сервисы получаем.
    service3(serviceProvider.service3()),
это детали реализации, и тебя не должны волновать :)
но опять же, посмотри на чит с статической переменой - так сказать кеш.
Который сводит на нет - твой приём.

разве что у тебя более явно, но стоит ли овчина выделки?

> По идеи зависимости сервисов уже хватит, чтобы вычислить ту последовательность,
> в какой их создавать и указывать в xml отдельно это не нужно.
> Единственное, что можно добавить - это ленивость сервиса. То есть если не
> указано специально, то сервис не создаётся, пока не потребуется и может не
> создаться до завершения приложения.
Еще пару минут и ты откроешь для себя Windows Services ^_^

#39
18:28, 31 янв. 2014

IROV..
> ServiceProvider - должен иметь виртуальный интерфейс, по этому не совсем корректно.
В нашем проекте не используются виртуальные функции до того, как без них не обойтись. Не считаю это плюсом, но скорости говорят добавляет. Сейчас садиться и заводить для всего виртуальные интерфейсы уже не охота. Написано много. Ну и если сделать ServiceProvider виртуальным, тогда придется кастить, а это перенос всех ошибок на время выполнения. Хотелось бы избежать.

> Windows Services
А можно подробнее? Типа COM, ActiveX, Soap, Corba?

> но опять же, посмотри на чит с статической переменой - так сказать кеш.
> Который сводит на нет - твой приём.
Почему сводит на нет? Типа кто-то завел переменную глобальную и пользуется ей, вместо того, чтобы пользоваться сервиспровайдером? Ну тогда сам виноват.

#40
18:36, 31 янв. 2014

laMer007
>>В нашем проекте не используются виртуальные функции до того, как без них не обойтись
кастуйте к void * и будет вам счастье.

>>а это перенос всех ошибок на время выполнения
что тут плохого? на этапе bootstrapper все выловите

>>А можно подробнее?
services.msc - там будут сервисы так вот они и имеют все эти зависимости, порядок запуска и Лейзи и не Лейзи


>>Почему сводит на нет? Типа кто-то завел переменную глобальную и пользуется ей, вместо того, чтобы пользоваться сервиспровайдером? Ну тогда сам виноват.
почитай внимательно код, геттера сервиса

#41
18:45, 31 янв. 2014

IROV..
> services.msc - там будут сервисы так вот они и имеют все эти зависимости, порядок запуска и Лейзи и не Лейзи
Ну сервисы мы не пишем. Я подумываю использовать виртуальные или не виртуальные сервиспровайдеры или иок контейнеры для разруливания зависимостей между объектами в крупной системе, а синглтоны отправить на помойку истории. Их реально много стало. Все что с ними - просто напрочь не тестируемо и не тестируется. Так что нужно избавляться, пока совсем не поздно. Вот думаю чем заменить.

#42
18:56, 31 янв. 2014

laMer007
>>Ну сервисы мы не пишем.
Изучи как они работают))

>>Так что нужно избавляться, пока совсем не поздно. Вот думаю чем заменить.
Я заменил, не жалею

#43
19:11, 31 янв. 2014

IROV..
Спасибо за поддержку. :)

Executor
IROV..
aruslan
Рад был повидать. :) Вы вроде давно к нам не заходите. С 2008 наверное не особо бываете... aruslan к сожалению не помню. Может сильно давно ушли...

#44
0:51, 1 фев. 2014

Executor
> os::file config = os::loadConfig("config.xml");
> И в каком месте тут синглтоны?

Если вам так будет понятнее, то для сравнения:

os::file config = os::getInstance().loadConfig("config.xml");

Смысл тот же, но дизайн использования немножко другой.

+ Показать
Страницы: 1 2 3 4 Следующая »
ПрограммированиеФорумОбщее

Тема в архиве.