1. C++ / Говнокод #14456

    +4

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    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);
    ...

    оттуда

    Запостил: LispGovno, 31 Января 2014

    Комментарии (146) RSS

    • Я вообще не понимаю о чем они и зачем катать квадратное колесо.
      Ответить
      • Покатаем квадратное колесо: http://ideone.com/MgbdwF

        + wiring во время компиляции, забыть какие-то зависимости попросту невозможно
        + никаких виртуальных методов, ммаксимум перформанса
        + абсолютная развязка между модулями

        - рукопашный wiring
        - прощай, автокомплит, нам будет тебя не хватать.
        - весь код в ашках, собираться будет часами (хотя геймдев оценит, ибо производительность)
        Ответить
        • У нас так и делают. Чем тебе не нравится? Чтобы долго не компилировалось - используем один сипипишник со всеми хедерами. Компилируется быстро. Не говнокод. Даже хацкел также делает, только шаблоны писать не нужно.
          Ответить
          • У нас или так или синглтоны. А у тебя как в коде? На каждый пук интерфейс заводишь? Я борманду и роману. Не себе
            Ответить
            • > А у тебя как в коде?
              Конкретные имена классов, как у последнего нуба ;)

              > Чем тебе не нравится?
              По большей части из-за "прощай, автокомплит, нам будет тебя не хватать".

              Ну и если циклическую зависимость захочется - двойной облом из-за иньекции в конструктор и статического полиморфизма. Хотя циклические зависимости не нужны.
              Ответить
        • александреску одобряет
          Ответить
          • Когда он такое говорил? Ему нравятся вычисления во время компиляции.

            Между прочем этот код для списков типов идеален. Все типы полные и не являются базовой абсракцией, а чистая конкретика. Конкретнее некуда.
            Ответить
            • Кстати, при желании можно завайрить и с абстрактным классом, все будет работать, там же в конструктор пропихивается ссылка ;)

              http://ideone.com/aEBSFM
              Ответить
              • Тогда передача в шаблоны абстрактных классов бесполезна. Ты производительность теряешь. Не быть тебе гейдевщиком.
                Ответить
                • > Тогда передача в шаблоны абстрактных классов бесполезна.
                  Я всего лишь хотел показать, что даже если вдруг понадобится передать туда абстрактный класс (ну например мутим циклическую зависимость) то код не придется переписывать ;)

                  > Ты производительность теряешь.
                  Само собой.

                  > Не быть тебе гейдевщиком.
                  Печаль-беда...
                  Ответить
                  • > Печаль-беда...
                    Я рад что ты это понимаешь. Но ты же понимаешь, что не всё потеряно! Измени себя!
                    Ответить
            • > Когда он такое говорил?
              Так у него вся книга про policy-based programming, не?
              Ответить
      • А что квадратного? Хочу избавится от синглтонов хоть как-нибудь. Я гарантирую, что они не нужны.
        Ответить
        • > А что квадратного?
          Да как-то оно не устраняет зависимости, а наоборот усложняет код и создает новые... Конфигурация сервисов перемешана с самими классами.
          Ответить
    • > Geter
      Гетера мужского пола?

      > Я вообще не понимаю о чем они
      Какая-то кривожопая реализация dependency injection?
      Ответить
      • Наверное
        Наверное
        Ответить
      • http://www.gamedev.ru/code/forum/?id=185532&page=3#m35
        Какой-то хренью занимаются. Синглтоны им не угодили.
        Ответить
        • а вообще я буду делать так

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


          Ха! Геймдев потихоньку превращается в Ынтырпрайз.
          Ответить
          • Нормальный геймдев всегда Ынтерпрайз. Всякие крузисы да ассассины
            Ответить
            • Ололо. Сам ты ынтерпрайс. Не ругайся матом.
              Ответить
              • >>Ха! Геймдев потихоньку превращается в Ынтырпрайз.

                правильно

                >>Нормальный геймдев всегда Ынтерпрайз.

                неправильно

                Я так понимаю вы меня ненавидите)
                Ответить
                • Нет. Борманд сказал, что гейдев хороший, но немного превращается в говно, а ты сказал, что гейдев всегда был говном. Теперь я тебя ненавижу.
                  Ответить
                  • Не юзал зеленый - значит в исконном смысле

                    http://static2.wikia.nocookie.net/__cb20110314162138/mlpfanart/images/0/05/Pinkie_Pie_haters_gonna_hate.gif
                    Ответить
    • bormand
      > Конфигурация сервисов перемешана с самими классами.
      Это паттерн такой, Service Locator. От того такое название. К сервисам отношения не имеет. Только в данном случае паттерн несколько извращенный, но не суть. Предназначен для введения зависимостей в классы.
      Ответить
      • > К сервисам отношения не имеет.
        Да ну? Ты же не думаешь, что я говорю о виндовых службах? :)

        Есть классы, предоставляющие некий сервис (логгер, ресурс манагер и т.п.), другие классы хотят их юзать и спрашивают ссылку на них у сервислокатора (в твоем случае почему-то названного service provider'ом). Так что вполне так имеет отношение к сервисам.

        > несколько извращенный
        Мягко сказано... Я не завидую тому, кто будет поддерживать подобный код. Тут же добавление нового класса, который от чего-то зависит и кому-то понадобится - +1 "сервиспровайдер". Поменять порядок инициализации - перепиливать пару сервиспровайдеров.
        Ответить
        • В данном случае сервис провайдер не влияет на порядок создания объектов. Тут он просто сборник ссылок на возможные зависимости, которые уже созданы. Хотя конечно провайдер состоит из функций и действительно может лениво создавать какие-то зависимости.
          Ответить
    • Ладно, мне стало интересно, как мог бы выглядеть этот код без этого "паттерна".
      Ответить
      • class Service1
        {
        public:
          Service1(Service2& service2, Service3& service3, Service3& service3, Service4& service4, Service5& service5):
            service2(service2),
            service3(service3),
            myMember1(service1, service2, service3, service4),
            myMember2(service1, service4, service5, service3),
            myMember3(),
            myMember4(service1, service2, service3, myMember2),
            myMember5(service1, service2, service3, myMember3),
            myMember6(service1, service2, service3, myMember2, myMember3)
          {}
          ...
        };
        ...
        Servive1 service1(service1, service2, service3, service4, service5);
        Service8 service8(service1, service2, service3, service4, service5);
        Service9 service9(service1, service2, service3, service4, service5);
        ...
        Куча копипасты, кучи параметров.
        Ответить
        • Допустим я в сервис провайдер упакую не всё, а наиболее популярные вещи, которые не меняются, например:
          систему логирования, систему системных событий, ... надо ещё подумать что туда занести. Остальное можно передавать обычными параметрами.
          Ответить
          • А вобяз нужна compile-time гарантия, что все инициализируется в правильном порядке?

            Просто без нее можно запилить один универсальный локатор в духе locator.put(log); Logger &log = locator.get<Logger>(). При неправильном порядке просто кинет экцепшн при старте. На производительности особо не скажется, т.к. ты все эти поля один хрен выписываешь при старте, а не дергаешь из локатора каждый раз.
            Ответить
            • Я люблю compile time гарантии. Сильно правильный порядок наверное не нужен.
              Ответить
            • Я бы взял IOC контейнер для С++, но что-то они все как один унылы.
              Ответить
            • Процитирую то, что уже писал на гейдеве:

              Теперь куча зависимостей спрятана в общий класс и в случае очень глубокой иерархии и куч объектов на разных уровнях (требующего примерно одинаковых зависимостей или меньше зависимостей) получает практически один параметр. В некоторых случаях будет меньше писанины. Ошибки типизации не переносятся на этап выполнения. Ошибки поиска зависимостей опять же не переносятся на этап исполнения. Интерфейсы можно не выделять, если это важно для приложения ради высокой производительности. То есть ради производительности не используются виртуальные функции, не используется поиск в иок контейнере, используются объекты на стеке или глобальные, используются самый конкретный потомок, а не какой-то его предок. В случае рефакторинга не придется заменять всюду по коду кучу зависимостей во всех параметрах, тк однажды упаковав новый в сервис провайдер сервис - он будет заменен на всех уровнях ниже по иерархии владения во всех экземплярах классов, куда передавали сервис провайдер.



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


              Я подумываю использовать виртуальные или не виртуальные сервиспровайдеры или иок контейнеры для разруливания зависимостей между объектами в крупной системе, а синглтоны отправить на помойку истории. Их реально много стало. Все что с ними - просто напрочь не тестируемо и не тестируется. Так что нужно избавляться, пока совсем не поздно. Вот думаю чем заменить.
              Ответить
              • > То есть ради производительности не используются виртуальные функции, не используется поиск в иок контейнере
                Ну IoC же не заставляет тебя юзать интерфейсы и создавать объекты в куче. Ты же вполне можешь пихать и вытряхать из него конкретные классы, инстанциированные на стеке main'а. На задержку тут всем похрен, ибо это всего лишь инициализация, а не горячий цикл.

                > Ошибки типизации не переносятся на этап выполнения.
                С IoC тоже не переносятся. Там только ошибки поиска зависимостей, но они опять же отловятся на первом запуске, т.к. вся конфигурация IoC'а у тебя забита в статику.
                Ответить
                • Переработать код с кучей синглтонов под IOCС я боюсь у меня не хватит времени и сил сейчас. Код за собой хранит ещё большее скрытое неподъёмное говно)
                  Ответить
                  • Сервис провайдер был бы более простой альтернативой, которая позволит провести тестирование. И просто внедрить зависимости. Да и "упоротые" иок контейнеры боюсь команда моя не оценит.
                    Ответить
                  • А если вот такой примитивный сервислокатор: http://ideone.com/Xz5FQ2
                    class locator {
                    public:
                        template <class T> void put(T &t) {
                            objects.insert(std::make_pair(&typeid(T), &t));
                        }
                        template <class T> T & get() {
                            objects_map::iterator it = objects.find(&typeid(T));
                            if (it == objects.end())
                                throw "shit!";
                            return *reinterpret_cast<T*>(it->second);
                        }
                    private:
                        typedef std::map<const std::type_info *, void *> objects_map;
                        objects_map objects;
                    };
                    Ответить
                    • http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/
                      А я от этих проблем избавился почти.
                      Ответить
                    • Ну допустим я захочу выпереть Bar и заменить на Foobar в половине экземпляров классов? А локатор-зараза общий. Придется прошариться по всем классам, юзающим локатор, и заменить на другой тип, но это не поможет все равно из-за того что вы написали такую простую реализацию, а я не использовал виртуальные интерфейсы или шаблоны класса, чтобы подменить тип легко в разных инстансах одного типа.
                      Ну и использовать для идентификации типа сам тип никак нельзя. Только если тип-спутник. Тк часто нужно для одного типа много экземпляров. У вас получился локатор синглтонов. У меня их конечно много, но не все же. Ну и от синголтонной болезни вообще хочется избавиться.
                      Ответить
                      • > У вас получился локатор синглтонов.
                        Так точно ;) Тут согласен, надо что-то более специфичное, чем айдишку класса.

                        > Ну допустим я захочу выпереть Bar и заменить на Foobar в половине экземпляров классов?
                        Так на той реализации один хрен это не выйдет... Классы же не шаблонные, а зависимости у них не абстрактные. Точно так же придется перепиливать кучу кода, заменяя Bar на Foobar во всех классах, которые захотят его юзать.
                        Ответить
                        • Ну у меня сервис провайдер маленький (данные преимущественно для какого-то куска подветки). Это значит, что я банально сделаю два или более экземпляра с разными ссылками и разным раздам разные. Более того методом как в myServiceProviderGeter базовый присланный свыше провайдер переделаю на другой если что.
                          Ответить
                          • А че толку то, дело же не в сервиспровайдере. Дело в самих сервисах, в которых захардкожены имена классов.

                            Может быть ты имел в виду раздачу разных инстансов одного класса разным классам? Вот тут да, с моей реализацией жопа, т.к. она по сути коробка с сигнлтонами.
                            Ответить
                    • Кстати не работает для классов с интерфейсами. У нас их не совсем нет, а есть там где без них не обойтись.
                      Ответить
                    • boost, stl, Loki используем.

                      Я бы хотел такой IOCC:
                      1)Что бы сам разруливал зависимости и управлял созданием объектов в правильном порядке, передавая нужное число влияющих параметров (сервисов) в конструктор или иногда в сеттер (хотя последнего у нас вроде пока нет, но обязательно появится с переносом кода из другой ветки).
                      2)Можно регать часть сервисов (как bormand::locator->put), тк сразу перевести все на иокк не получится.
                      3)Нужен механизм зависимости от событий. То есть чтобы по мере создания объектов дергались некоторые зарегистрированные функции. У нас нет возможности все зависимости описать объектно. Есть конечно, но это будет очень накладно, тк реально в конструктор эту зависимость придется передать, а по факту её объектной формой пользоваться не придется. Через событийные зависимости думаю описывать и вариант с сеттером, тк у него может быть нестандартное название.
                      4)Не плохо бы по максимуму сохранить ошибки компиляции и автоматизацию. Поэтому пусть вместо традиционных строк будут типы-спутники экземпляра класса. Это позволит передавать не T в get, а T_descriptor условно говоря. И тогда возвращаемое значение get может само вычисляться. Ну и неплохо бы дать указывать возвращаемое значение get, чтобы поддержать типы с наследованием.
                      5)Описание в XML не мешает конечно, но не нужно. Не плохо бы описание в EDSL. Какой едсл стиль для этого выбрать, если самому придется писать?

                      Что-то подобное есть на примете из готового? Систем с зависимостью от событий не видел. А тут это корневой момент, избавится от них нельзя.
                      Ответить
                      • Нинужно.
                        Ответить
                      • > Я бы хотел такой IOCC:
                        Я джва года хочу такой контейнер.

                        > Что-то подобное есть на примете из готового?
                        Х.б.з., я крестовые IoC вообще не раскуривал.

                        Судя по тому, что они не особо развиваются - не особо это и реально.
                        Ответить
                        • > я крестовые IoC вообще не раскуривал.
                          А как тогда вы с зависимостями боретесь?

                          > Судя по тому, что они не особо развиваются
                          Я штук десять нашел сходу. Документацию ну наверное по 3-4ом. Те что без смотреть не стал.

                          > Я джва года хочу такой контейнер.
                          Тут это значит что не хотите? Тогда почему?
                          Ответить
                          • > А как тогда вы с зависимостями боретесь?
                            Синглтон с закатом солнца вручную (SomeShit::initialize(42, "100500")). Или рукопашная передача.

                            > Я штук десять нашел сходу.
                            Да, их полно, но что-то процент дохлятины, которую 5 лет не трогали, среди них очень велик.

                            > Тут это значит что не хотите?
                            Не, это просто прикол был, цитата из "корованов".
                            Ответить
                            • Вы конечно не знаете требований к моей системе, но все же. Неужели нет замечаний? Ну или может если бы у вас такой был, то вы им пользовались бы?

                              Идеи с EDSL для описания зависимостей есть?
                              Ответить
                              • > Неужели нет замечаний?
                                Про зависимость от событий не совсем понятно. Некие коллбеки, вызываемые до и после создания некоторых инстансов?

                                > передавая нужное число влияющих параметров (сервисов) в конструктор
                                В крестах это хрен запилишь без бойлерплейта или кодогенерации - рефлексии же нет.

                                > Идеи с EDSL для описания зависимостей есть?
                                Тут надо подумать.
                                Ответить
                                • > Тут надо подумать.
                                  Пока только вот такой "EDSL" в голову приходит:
                                  http://ideone.com/LWH6ye
                                  c.add_factory<game, game>([&] () -> game * {
                                      c.resolve<sdl>(); // external dependency without real object
                                      return new game(
                                          c.resolve<abstract_logger>(),
                                          c.resolve<config>(),
                                          c.resolve<resource_manager>()
                                      );
                                  });
                                  Иньекцию через сеттер можно делать сразу перед return'ом. Механизм событий о загрузке - сама фабрика. Регать готовые сервисы даже сейчас можно - просто зарегать фабрику, возвращающую готовый сервис. Порядок инициализации - определяет сам по зависимостям.

                                  Естественно это всего лишь концепт, и пока работает только в режиме синглтона. Ну и в данном коде нету многих важных проверок и не решена проблема управления памятью...
                                  Ответить
                                  • Можно еще написать простенький хелпер для типичных ситуаций:
                                    c.add_simple_factory<game, game,
                                        abstract_logger,
                                        config,
                                        resource_manager>();
                                    А в метод add_factory можно передать режим кеширования:
                                    - no_cache - контейнер тупо возвращает то, что вернула фабрика, и вызывает ее каждый раз
                                    - cache - аля обычный синглтон
                                    - tls_cache - thread-local синглтон
                                    Ответить
                                    • Тебе не кажется, что это всё очень упорото? Зачем городить хрустальные замки из шаблонов, когда можно просто по человечески и понятно писать код. У того парня крыша от шаблонов поехала, ты то не съезжай. Сам то веришь, что это можно использовать в промышленном программировании?
                                      Ответить
                                      • > ты то не съезжай
                                        Если бы я съехал - тут бы уже была ссылка на гитхаб с just another c++ IoCC.

                                        > по человечески и понятно писать код
                                        Окай, спущусь с небес на землю:
                                        int main() {
                                            config cfg;
                                            file_logger log(cfg);
                                            resource_manager rm(log, cfg);
                                            game g(log, cfg, rm);
                                            g.start();
                                            return 0;
                                        }
                                        Но это же скучно :)
                                        Ответить
                                  • Ошибка компиляции. товарищ
                                    Ответить
                                    • > Ошибка компиляции. товарищ
                                      Вижуалстудия? Текст ошибки кинь.
                                      Ответить
                                      • В самой ideone.
                                        Текст большоооой
                                        Ответить
                                        • > В самой ideone.
                                          Блеать, я запостил и не посмотрел, что с++11 не включил. Спасибо!

                                          http://ideone.com/UIra6C
                                          Ответить
                                          • Не за что. а теперь скажи что это. мне нужно отвлечься от всяких визитеров-компоновщиков - повтыкаю
                                            Ответить
                                            • > а теперь скажи что это
                                              Это жалкая пародия на IoC контейнер.

                                              Ты описываешь контейнеру зависимости между классами (в данном случае через container::add_factory()), а затем можешь просить его запиливать инстансы этих классов. Все необходимые зависимости автоматически создадутся и инжектнутся ему через конструктор или свойства.
                                              Ответить
                                              • а, старый добрый DI.

                                                Я ninject юзал под .net, в курсе что - кого.

                                                Как это меня жизнь скрутила, коль я для расслабона IoC на плюсах смотрю
                                                Ответить
                                              • ммм, а зачем ты всовываеim 2 раза тип? или это бетка, и потом будет кошерное <base, concret>? Ну я так понимаю явный порядок внедрения зависимостей тоже временная мера
                                                Ответить
                                                • > явный порядок внедрения зависимостей
                                                  Нет, постоянная. Это ж кресты. Рефлексии нету. Либо кодогенерация, либо адское шаблоноебство (и не факт, что получится), либо вот так вот перечислять все зависимости в том порядке, как они идут в конструкторе. Если в конструкторе кто-то поменяет порядок - компилятор сматерится, а ты просто переставишь их местами.

                                                  > всовываеim 2 раза тип
                                                  Первый - тег, второй реальный тип. Тег нужен чтобы например 2 разных лога зарегать, и отдать половине классов первый, а половине - второй.

                                                  > это бетка
                                                  Да какая это бетка, это так, набросок для иллюстрации идеи, даже на пруф оф концепт не тянет.
                                                  Ответить
                                                  • >>Нет, постоянная

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

                                                    >>

                                                    а почему тогда

                                                    c.add_factory<abstract_logger, abstract_logger>

                                                    а не

                                                    c.add_factory<abstract_logger, file_logger>

                                                    или не

                                                    c.add_factory<abstract_logger>

                                                    (на счет последнего не уверен, но там вреде как по умолчанию стоит 2 параметр=первому)

                                                    ?
                                                    Ответить
                                                    • > а не
                                                      Идея примерно такая - допустим нам надо часть инфы отправить в особый лог (глупый пример, но пох), тогда мы делаем так:
                                                      class debug_logger {};
                                                      class normal_logger {};
                                                      
                                                      c.add_factory<debug_logger, abstract_logger>(...);
                                                      c.add_factory<normal_logger, abstract_logger>(...);
                                                      
                                                      new game(
                                                          c.resolve<debug_logger, abstract_logger>(),
                                                          ...
                                                      );
                                                      
                                                      new resource_manager(
                                                          c.resolve<normal_logger, abstract_logger>(),
                                                          ...
                                                      );
                                                      И гейму попадет отладочный лог, а менеджеру ресурсов - обычный. По идее второй параметр надо бы заныкать в первый, в духе struct debug_logger { typedef abstract_logger type; } и передавать только один параметр, но лень...
                                                      Ответить
                                                      • то есть сначала идет конкретный класс, а потом интерфейс?

                                                        Я просто наоборот привык)

                                                        Ninject.Bind<IWeapon>().To<Sword>();
                                                        Ответить
                                                        • > то есть сначала идет конкретный класс, а потом интерфейс?
                                                          Да почему, так как ты написал, так и есть.
                                                          Сначала тег и интерфейс (но можно и конкретный класс, для совместимости со старым кодом). Затем фабрика, возвращающая конкретный класс:
                                                          c.add_factory<IWeapon, IWeapon>([&] () -> IWeapon * {
                                                              return new Sword(
                                                                  c.resolve<Blade>(),
                                                                  c.resolve<Handle>()
                                                              );
                                                          });
                                                          Просто есть еще дополнительная возможность - два инстанса одного класса можно засунуть, пометив их разными тегами.
                                                          Ответить
                                                          • а, все, понял. у тебя конкретный класс не указывается и поэтому юзается тег, что можно было различить резные связки. А конкретика только в прямой привязке.

                                                            Ну то есть что возвращает - то и привязано)
                                                            Ответить
                                                      • оффтоп

                                                        сижу, освежаю паттерны в голове. наткнулсяна декаратор - не могу понять что за хрень. тупил минут 10 глядя на схему. А потом такой - аааа, так этож бездна анального делигирования.

                                                        мораль сей басни такова - пишите статью - приводите нормальные примеры как я)
                                                        Ответить
                                  • >такой "EDSL"
                                    Не увидел EDSL.
                                    Ответить
                          • >>А как тогда вы с зависимостями боретесь?

                            А зачем с ними бороться?
                            Пусть жависты борются с ними мегабайтами xmlя, фабриками фабрик, синглтонами и декораторами.
                            Я серъезно. В каких частоиспользуемых популярных программах сделано это ваше IoC.
                            Ответить
                            • >> А как тогда вы с зависимостями боретесь?
                              > А зачем с ними бороться?
                              Не имеет смысла бороться с зависимостями. Зависимости - это часть тебя. Я вот курю.
                              Ответить
                            • а я думал ты брат-жабист...

                              IoC - не серебряная пуля. Но она существенно помогает поддерживать проект. Все становиться модульным и заменяемым. Ня!
                              Ответить
                              • > Все становиться модульным и заменяемым.
                                Только вот на практике никто никогда ничего не заменяет :) Потому что работает - не трогай.

                                Лучше бы тестирование в качестве примера привел, для него пользы от IoC побольше.
                                Ответить
                                • В тестировании от мокинга больше пользы

                                  Но так как мокинг на интерфейсах строится, то и ioc весьма кстати)
                                  Ответить
                                • >>Только вот на практике никто никогда ничего не заменяет
                                  Вот, учитесь. Слова понявшего жизнь кодера. +100500
                                  90% оверинжинирнга в программировании от того что пытаются писать слишком модульный, слишком расширяемый и слишком заменяемый код.
                                  Ответить
                              • Сколько программ которыми пользуешься каждый день лично ты написано с применением IoC?
                                Браузер, торрент-клиент, кодеки, среда разработки, контроль версий, компилер, виртуальная машина - да ни одна из них.
                                И весь этот софт гораздо сложнее того что пишем мы.

                                Ладно какие известные софтины/либы самой жабы написаны с использованием IoC? На ум приходит только мавен.
                                Ответить
                                • спринг разве не пропагандирует иок?
                                  Ответить
                                  • пропагандирует. в этом и беда.
                                    Ответить
                                    • > в этом и беда
                                      ну и пусть. фанатикам всегда нужна религия. тебя это чем-то задевает? юзаю синглтоны, доволен как рак
                                      Ответить
                                • Да я вообще студент, в исходниках жабы не копался.)

                                  Я говорю о том, что так писать выгодно с точки зрения разработки, а само написание не требует усилий. Примеры не могу привести, разве только что из личного опыта написания лаб)
                                  Ответить
                                  • Лабы выгодно писать без применения Ioc, уверяю.
                                    Ответить
                                    • > Лабы выгодно писать без применения Ioc, уверяю.
                                      Я вообще 99% лаб делал консольными, чтобы не засорять их лишним кодом.
                                      Ответить
                                    • > Лабы выгодно писать
                                      Лабы выгодно сдавать, уверяю.
                                      Ответить
                                    • Ну когда я писал ген. алгоритмы для комивояжера я сделал несколько классов кроссинговера и мутации, да и сам класс ген алга через интерфейс вставил. потм на след лабе нужно было другой метод применить - дописал либу - добавил кнопку
                                      Ответить
                                      • Контекст поднимал, бины инжектил:?

                                        >>дописал либу - добавил кнопку
                                        А нужен ли нам для этого IoC? Не надо путать контрактное программирование и DI.

                                        Во всех других языках программы каким-то образом успешно работают и без этого порождения Фаулера.
                                        Ответить
                                        • IoC - да. У нас не было зависимости от конкретного класса - все через интерфейс. Поэтому и не было проблем с добавлением новой функциональности
                                          Ответить
                                          • >>IoC - да. У нас не было зависимости от конкретного класса - все через интерфейс.

                                            Повторюсь:
                                            >>>Не надо путать контрактное программирование и DI.
                                            Ответить
                                            • >>IoC
                                              >Не надо путать контрактное программирование и DI.

                                              Я бы сказал, не надо путать loC и DI. Первое как раз заключается в том, что классы зависят только от интерфейсов. Второе подразумевает внедрение реализаций с помощью middleware - IoC-container. Так что в этом вопросе я скорее на стороне кегдана.
                                              Ответить
                                              • ты пользуешь iocc?
                                                Ответить
                                                • > ты пользуешь iocc?
                                                  По работе всегда приходилось использовать spring. В личных проектах предпочитаю Guice, он весьма приятен в обращении.
                                                  В крестах не использую.
                                                  Ответить
                                                  • >>В крестах не использую.
                                                    А как же там борешься с зависимостями?
                                                    Ответить
                                                    • > А как же там борешься с зависимостями?
                                                      Явная инициализация всего, что нужно, в main.
                                                      Ответить
                                                      • Типа ручной вайринг всего и вся?
                                                        Ответить
                                                        • > ручной вайринг
                                                          Ну да. Да и типичные крестопроекты обычно не плодят столько абстракций, там вайринга не так много.
                                                          Опять же, на текущем месте работы принято разрабатывать небольшие, специализированные сервисы и интегрироваться через xml-rpc/json-rpc. Так проще обеспечить отказоустойчивость, репликацию и балансировку нагрузки. Или поменять язык реализации при необходимости.
                                                          Ответить
                                                          • >обычно не плодят столько абстракций, там вайринга не так много

                                                            Я практически не слышал чтобы проекты (даже громадные) на сишке, крестах использовали какие-либо фреймворки для вайринга. Равно как не слышал что кто-то сильно от этого страдал и жаловался.

                                                            Так вот я и думаю может все эти iocc - жабизм головного мозга. Создаём себе кучу проблемабстракций, а потом пытаемся с ними как-то управиться.

                                                            PS А создатель спринга кстати уже ушёл в контору к Одерски.
                                                            Ответить
                                                        • > Типа ручной вайринг всего и вся?
                                                          А я для всяких логов, конфигов и прочей хрени, которая 100% одна на проект предпочитаю синглтоны с ручной инициализацией через class_name::initialize().

                                                          - можно забыть инициализнуть (что отловится по ассерту на первом же отладочном пуске)
                                                          + не надо заморачиваться с передачей (иньекции без контейнера - для мазохистов)
                                                          + шустро и на 146% потокобезопасно (что в ленивых синглтонах достигается медитацией и плясками, если вообще достигается)
                                                          + киллер фича: можно передать аргументы
                                                          Ответить
                                                          • >>что в ленивых синглтонах достигается медитацией и плясками
                                                            Кстати да. От ленивых синглтонов профита обычно мало, а вот гемора - много.

                                                            Мы слишком ленивы чтоб писать истинно ленивые синглтоны!
                                                            Ответить
                                                          • > что в ленивых синглтонах достигается медитацией и плясками, если вообще достигается

                                                            Ололо, жаба и нетфреймворка -батхерт. ВКрестах проблем нет, брат жив.
                                                            Ответить
                                                            • > ВКрестах проблем нет, брат жив.
                                                              Ок, теперь передай ленивому синглтону аргументы.

                                                              > ВКрестах проблем нет
                                                              Нет тредов - нет проблем.

                                                              P.S. А какой из способов юзал брат, который жив?
                                                              Ответить
                                                              • парни, оффтоп.

                                                                Вы не любите меня, я не люблю вас, но завтра у меня в 9 утра по Москве собеседование на должность программиста .NET

                                                                Материте меня, сволочи
                                                                Ответить
                                                              • > Ок, теперь передай ленивому синглтону аргументы.
                                                                static Singleton& Singleton::instance(){
                                                                static Singleton I(arg1, arg2, arg3);
                                                                return I;}
                                                                Problems? %)
                                                                Ответить
                                                                • > Problems? %)
                                                                  И хде он взял arg1, arg2, arg3? %)

                                                                  P.S. И ты же сам вроде бы писал, что этот синглтон мейерса непотокобезопасен в некоторых компиляторах...
                                                                  Ответить
                                              • >>Второе подразумевает внедрение реализаций с помощью middleware - IoC-container

                                                Насколько я понимаю речь с самого начала треда идет именно об инжекциях имплементаций и IoC-контейнерах. А не :
                                                >>том, что классы зависят только от интерфейсов
                                                Если вырвать мои слова из контекста треда, то да.
                                                Ответить
                                            • эээ, сорри, может я в терминологии путаюсь.

                                              Контрактное программирование - это вообще не то

                                              IoC - ослабление зависимости через интерфейс - так?
                                              Ответить
                                              • >>IoC - ослабление зависимости через интерфейс - так?
                                                Так. Но я предпочитаю терминологию:
                                                "ослабление зависимости через интерфейс"=="контрактное программирование"
                                                IoC в смысле IoC-контейнер (да я забываю лишнюю С), который сам начиняет другие объекты.

                                                То бишь делает wiring, о котором борманд написал изначально comment214212
                                                Ответить
                                                • http://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BD%D1%82%D1%80%D0%B0%D0% BA%D1%82%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80% D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B 8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0 %B5

                                                  это даже близко не то- контрактное программирование

                                                  ioC и ioCC - вещи разные) iocc я не юзал - это сильно гибко, мне так не нужно было)
                                                  Ответить
                    • а вот у меня к тебе другой вопрос: разве это правильно сервисы идентифицировать их типами?
                      Ответить
                      • Ну если однотипные сервисы не нужны - почему нет?
                        А если нужны - то само собой неправильно.
                        Ответить
                        • Ну логично, просто я видел похожее, и там люди начали делать туеву хучу маркеных классов, и мне это показалось убожеством.
                          Типа такого:
                          BackupUserSessionsMongoDataService extends BackupDataService<UserSessionsMongoDataService>
                          UserSessionsMongoDataService extends MongoDataService<Session>
                          Ответить
                        • Да и вообще такая штука, как по мне, может быть скорее анти-паттерном, ибо она скрывает явный граф зависимостей, что прямо влияет и на юзабилити класса, и на тестабилити (в худшую сторону).
                          Ну все выше сказанное - мое имхо, и может быть оспорено.
                          Ответить
                          • Ну вот в том же андроиде разрабы были вынуждены замутить сервислокатор. И там он совсем не антипаттерн, а суровая необходимость.
                            Ответить
                            • А можно подробнее о том, зачем он там нужен? (К сожалению, с адроидом не сталкиваться)
                              Ответить
                              • Просто андроид говно, ндк говно, гугл говно, с++ говно
                                Ответить
                                • Вот этот поинт я поддерживаю целиком и полностью, я вообще не понимаю, как все может работать, когда вокруг нас столько легаси на всех слоях.
                                  Но тред-то не про это...
                                  Ответить
                                  • А херли ты хотел, это легаси - оно не только в пограммном коде, оно везде, к конструкции человека, в конструкции вселенной...
                                    Ответить
                                    • Чувак, да бесспорно, второй закон термодинамики, если я не ошибаюсь, конечно.
                                      Энтропия системы всегда растет
                                      Ответить
                              • > зачем он там нужен
                                Добывать интерфейсы всяких служб. Например:
                                Vibrator vibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
                                Ответить
                                • показать все, что скрытоЗасунь себе в жопу ржавую трубу.
                                  Ответить
                                • Во-первых, спасибо за понимание.
                                  Во-вторых, не пойму, чем это лучше, чем
                                  Vibrator vibrator = context.getVibratorService();

                                  И в-третьих, согласись, что даже в текущем виде кода прокидывать этот context, везде и всюду - плохая идея.
                                  Хотя, есть еще более плохое решение - хранение подобного контекста в сингтоне.
                                  Ответить
                                  • Лучше тем, что не прибивает гвоздями список служб. На старых сотиках части служб нет, и если юзать твой способ - придется делать по проге под каждую версию. А так - все скомпилится и запустится, и функция просто вернет налл.

                                    А контекст... каждая активити (экранная форма) реализует контекст, каждый сервис, емнип, тоже. Поэтому с его добычей особых проблем нет.
                                    Ответить
                                    • Да он итак прибит энамом. А так будет списком методов. Разницы в поведении нет. Есть вибратор - будет тебе вибратор, нет вибратора - будет налл.
                                      Правда в моем случае нам не придется даункастить лишний раз, а это потенциальное место для ошибки.
                                      А то, что этот контест есть везде, как раз и есть та проблема, потому, что если ты захочешь, понять, что там РЕАЛЬНО нужно, или захочешь замокать все реальные дипенденсы, для теста, все, попа.
                                      Ну это как мне кажется.
                                      Ответить
                                      • Это не энам, это самая обычная строка.
                                        Ответить
                                        • Оу, логично, что-то я затупил.
                                          Но все равно, согласись, постоянно доставать все из контекста - плохая идея.
                                          Ответить
                                          • Моки навешать - да, проблема. Но с другой стороны это меньшая проблема при тестировании гуишного класса ;)

                                            А другим классам никто не заставляет передавать контекст целиком, там уже ты сам за все в ответе.
                                            Ответить
                                            • Это точно, хотя я не уверен, что гуишный класс должен напрямую дергать сервисы.
                                              Ответить
                                • 4 раза вибратор и это еще не рекорд!
                                  Ответить
    • Всё говно в фан(сервисе)
      Ответить
      • А тред об Аниме, ага.
        Ответить
        • Тссс...никаких слов на А! Налетят с вопросами про KDE...
          Ответить
          • Как пропатчить KDE под винду?
            Ответить
            • ЕМНИП, её не патчить надо, а сразу вендовый инсраллятор качать...
              Ответить
              • У меня Конкерор под Виндой часто падает. Что нужно пропатчить, чтобы он исправно работал?
                Ответить
                • А интернет эксплорер под питухом у тебя не падает?
                  Ответить
                • Konqueror нинужен
                  Ответить
                  • Как не нужен? А kio_slave? А кнопка «на уровень вверх»?

                    Это Интернет Эксплорер не нужен.
                    Ответить
                    • А чем тебе Backspace в эксплорере не угодил?
                      Ответить
                      • Backspace переводит назад, а не на уровень вверх.
                        Ответить
                        • он как - то через разжопу это делает) если по ярлыку в папку перейти - правильно выходит, на уровень выше. а дальше - магия...
                          Ответить
                          • А ещё некоторые сайтостроители через жопу сайты верстают. Например, можно в преамбуле страницы указать:
                            <link rel="prev" href="http://www.example.com/document/page100499" />
                            <link rel="next" href="http://www.example.com/document/page100501" />
                            Но вместо этого вставляют неудобные ссылки, которые ещё нужно найти на странице. А ещё забывают про rel="contents", rel="home", rel="up" и ещё про целую кучу нужных элементов, изобретая вместо них велосипеды.
                            Ответить

    Добавить комментарий