Здравствуйте, adontz, Вы писали:
A>Злоупотребление IServiceProvider не лучше. Программист "садится" на этот подход и начинает пихать в IServiceProvider не только опциональные зависимости, но и объязательные.
Вобще говоря все зависимости нужно конфигурить... так что...
A>В результате у нас не видно снаружи что реально требуется внутри и внутри появляется куча проверок if (service != null). Смысла в этом решительно никакого нет, код пухнет, смысла не добавляется. IServiceProvider имеет смысл использовать только как контейнер для передачи опциональных зависимостей. Причём достаточно неудобный контейнер, так как невозможно передать два однотипных объекта. возвращаясь к твоему примеру, ты не можешь передать два ILogger через IServiceProvider, и даже два FileLogger тоже не сможешь.
IServiceProvider это лишь пример. Вместо него можно использовать что-то другое.
A>Объязательные зависимости конфигурируемые снаружи передаются вно, типизированными параметрами.
А потом их станет больше...
И все переписывать...
A>объязательные зависимости не конфигурируемые снаружи (журналирование), особенно общие для нескольких компонент, надо делать синглтонами.
Оно таки конфигурируемое.
Например путь к логу, период логротейта, уровень логгирования...
A>Так лгче их поддерживать.
Нифига подобного.
A>Если у меня, например, есть две библиотеки, для SMTP и POP3, то мне удобнее не грузить приложение тем, что они что-то журналируют, пусть сами получают логеер-синглтон.
А самим получить логгер из контейнера не судьба?
A>Заодно я точно буду знать, что какой-нибудь гений неразобравшись не создаст им два разных экземпляра синглтона журналирования, хотя реальная фильтрация производится не рна уровне объектов, а на уровне источника сообщения "network.tcp.client.smtp", "network.tcp.client.pop3"
Ты вобще сейчас о чем?
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, adontz, Вы писали:
A>Это плохой пример и дело даже не в синглтоне, а в том, что ты фильтрацию сообщений выносишь за пределы системы журналирования и вместо того чтобы настроить "эти сообщения в первый журнал, эти во второй, эти в оба" начинаешь писать велосипеды. Вместо того чтобы управлять через конфиги, начинаешь писать if'ы. В этом смысле да, логгер должен быть один, а будет ли это синглтон уже отдельный вопрос.
Нет никаких if'ов.
Все конфигурится конфигом.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, adontz, Вы писали:
WH>>Если задумыватся о проектировании не начнут. A>Это смешно, делать подобные утверждения. На самом деле ты увеличиваешь связность.
Если уметь проектировать системы то нет.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
A>>Злоупотребление IServiceProvider не лучше. Программист "садится" на этот подход и начинает пихать в IServiceProvider не только опциональные зависимости, но и объязательные. WH>Вобще говоря все зависимости нужно конфигурить... так что...
ЗАчем конфигурировать объязательные зависимости?
A>>Объязательные зависимости конфигурируемые снаружи передаются вно, типизированными параметрами. WH>А потом их станет больше... WH>И все переписывать...
Если это объязательные зависимости, то тебе придётся переписывать далеко не только сигнатуры методов.
WH>Оно таки конфигурируемое. WH>Например путь к логу, период логротейта, уровень логгирования...
Этон е серьёзно. Надо делать фильтрацию сообщений.
A>>Если у меня, например, есть две библиотеки, для SMTP и POP3, то мне удобнее не грузить приложение тем, что они что-то журналируют, пусть сами получают логеер-синглтон. WH>А самим получить логгер из контейнера не судьба?
А зачем из контейнера? А вдруг не предали? Опять if (logger != null)?
A>>Заодно я точно буду знать, что какой-нибудь гений неразобравшись не создаст им два разных экземпляра синглтона журналирования, хотя реальная фильтрация производится не рна уровне объектов, а на уровне источника сообщения "network.tcp.client.smtp", "network.tcp.client.pop3" WH>Ты вобще сейчас о чем?
Я о том, что нет смысла делать два экземпляра Logger каждый из которых сконфигурировать писать сообщения с источником "network.tcp.client.smtp" в файл smtp.log, а сообщения с источником "network.tcp.client.pop3" в pop3.log, если потом одному будут посылаться только SMTP сообщения, а другому только POP3.
Здравствуйте, WolfHound, Вы писали:
A>>Это плохой пример и дело даже не в синглтоне, а в том, что ты фильтрацию сообщений выносишь за пределы системы журналирования и вместо того чтобы настроить "эти сообщения в первый журнал, эти во второй, эти в оба" начинаешь писать велосипеды. Вместо того чтобы управлять через конфиги, начинаешь писать if'ы. В этом смысле да, логгер должен быть один, а будет ли это синглтон уже отдельный вопрос. WH>Нет никаких if'ов. WH>Все конфигурится конфигом.
Тогда не должно быть никаких двух логгеров. Конфигом конфигурируй какие сообщения куда слать.
Здравствуйте, WolfHound, Вы писали:
WH>>>Если задумыватся о проектировании не начнут. A>>Это смешно, делать подобные утверждения. На самом деле ты увеличиваешь связность. WH>Если уметь проектировать системы то нет.
Заранее всего не предусмотреть. Чем меньше кода затрагивает конкретное изменение, тем лучше.
Здравствуйте, adontz, Вы писали:
A>ЗАчем конфигурировать объязательные зависимости?
Как зачем?
Например есть некий компонент (А). Этому компоненту нужны некоторые настройки.
Этот необходим другому компоненту (Б) для работы. Этому компоненту тоже нужны свои настройки.
А тут могут возникнуть разные ситуации:
1)Нужно два компонента Б которые используют один и тотже компонент А.
2)Нужно два компонента Б которые используют разные компоненты А.
Я это решаю конфигами. Вернее это решают вобще не трогая меня.
Ты переписыванием системы.
A>Если это объязательные зависимости, то тебе придётся переписывать далеко не только сигнатуры методов.
Не придется.
A>А зачем из контейнера? А вдруг не предали? Опять if (logger != null)?
А тебе не приходило в голову что контейнер можно специализировать?
И хранить в этом контейнере не только сервисы но и некие другие настройки текущего контекста?
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, adontz, Вы писали:
A>Заранее всего не предусмотреть. Чем меньше кода затрагивает конкретное изменение, тем лучше.
И я о томже... вот только ты не понимаешь что именно мое решение требует переделок меньше чем решение на синглетонах.
Факт многократно подтвержденный и не только мной.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>А тут могут возникнуть разные ситуации: WH>1)Нужно два компонента Б которые используют один и тотже компонент А. WH>2)Нужно два компонента Б которые используют разные компоненты А. WH>Я это решаю конфигами. Вернее это решают вобще не трогая меня. WH>Ты переписыванием системы.
Не, в примерах выше, я это решаю передачей А идентификатора Б и конфигами некоторого C — фильтра сообщений между всеми Б и всеми А (фактически там chain of responsibility). С другой стороны у меня нет отдельных сопрягающих конфигов и я могу строить очень сложные, динамически менямые зависимости когда много Б пишут во много А. Это более общее решение.
A>>Если это объязательные зависимости, то тебе придётся переписывать далеко не только сигнатуры методов. WH>Не придется.
Ну как же? А использовать? Или передать объект параметром — это цель, а обращаться к нему не объязательно?
WH>А тебе не приходило в голову что контейнер можно специализировать? WH>И хранить в этом контейнере не только сервисы но и некие другие настройки текущего контекста?
А какая принципиальная разница между специализированным контейнером и передайчей параметров? То есть какая принципиальная разница между
struct Container
{
public Service1 x;
public Service2 y;
}
void Action(Container container);
Здравствуйте, WolfHound, Вы писали:
A>>Заранее всего не предусмотреть. Чем меньше кода затрагивает конкретное изменение, тем лучше. WH>И я о томже... вот только ты не понимаешь что именно мое решение требует переделок меньше чем решение на синглетонах. WH>Факт многократно подтвержденный и не только мной.
Здравствуйте, adontz, Вы писали:
A>Не, в примерах выше, я это решаю передачей А идентификатора Б и конфигами некоторого C — фильтра сообщений между всеми Б и всеми А (фактически там chain of responsibility). С другой стороны у меня нет отдельных сопрягающих конфигов и я могу строить очень сложные, динамически менямые зависимости когда много Б пишут во много А. Это более общее решение.
Рома ты вобще о чем?
Что куда пишет? Какие еще сообщения? Какой еще С? Зачем динамически что-то менять если это менять не нужно?
Это как минимум овердизайн, а то и просто деверсия.
A>Ну как же? А использовать? Или передать объект параметром — это цель, а обращаться к нему не объязательно?
Использовать его будут там где он нужен.
И менять я буду только это место.
A>А какая принципиальная разница между специализированным контейнером и передайчей параметров? То есть какая принципиальная разница между
Вот такая
struct Container
{
public Service1 x;
public Service2 y;
public Service11 x1;
public Service21 y1;
public Service12 x2;
public Service22 y2;
}
void Action(Container container);
А если учесть что цепочка вызовов может быть весьма не маленькой...
И это вполне реальная ситуация. Я в одном месте начал с двух сервисов, а сейчас там уже 6.
И старый код которому нужно только 2 первых ни разу не менялся.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>А если учесть что цепочка вызовов может быть весьма не маленькой... WH>И это вполне реальная ситуация. Я в одном месте начал с двух сервисов, а сейчас там уже 6.
Это понятно, что сервисов вообще говоря будет много, а то и очень много.
WH>И старый код которому нужно только 2 первых ни разу не менялся.
Очень хорошо. С одной стороны у нас часть сервисов передаётся на низлежащие уровни, где они не нужны вообще, часть сервисов создаётся на уровне гораздо выше, чем реально используется. Нарушено время жизни. Это далеко не всегда принципиально, но всё же это следует учитывать. Кроме того, если тебе что-то понадобилось на нижнем уровне, тебе надо поменять класс ServiceContainer, поковыряться в верхнем уровне и добавить туда инициализацию, прекомпилировать все промежуточные уровни. По сравнению с plug'n'play синглтоном, ситуация уже. Другое дело, что чрезмерное использование синглтона вредно, как впрочем и чрезмерное использование чего угодно. вобщем я за решения принимаемые исходя из контекста задачи, а не из идеологии. Никто ведь не закладывает возможность двух принт-спулеров, потому что такое никогда не может понадобиться. Совсем никогда. Это даже не overkill, с расчётом на слетлое будущее, это абсолютное непонимание предметной области. Всё равно как выделить некоторый участок мозга на случай если вдруг родится человек с тремя глазами.
Здравствуйте, adontz, Вы писали:
A>Очень хорошо. С одной стороны у нас часть сервисов передаётся на низлежащие уровни, где они не нужны вообще,
И? На одном уровне не нужно. А на уровне ниже нужно.
И в чем проблема передать эти сервисы через уровень где они не нужны на уровень где они нужны?
Или скажем у меня есть интерпретатор в котором некоторые комманды используют одни сервисы, а некоторые другие.
Этот интерпретатор работает в несколько потоков и в каждом потоке нужны свои копии сервисов.
A>часть сервисов создаётся на уровне гораздо выше, чем реально используется. Нарушено время жизни.
Это еще с чего?
Сервисы создаются на том уровне который должен отвечать за время жизни этого сервиса.
Скажем сервисы уровня сессии создаются вместе с самой сессией и передаются в контексте дальше.
A>Это далеко не всегда принципиально, но всё же это следует учитывать.
Что именно?
A>Кроме того, если тебе что-то понадобилось на нижнем уровне, тебе надо поменять класс ServiceContainer, поковыряться в верхнем уровне и добавить туда инициализацию, прекомпилировать все промежуточные уровни. По сравнению с plug'n'play синглтоном, ситуация уже.
Упал до стол.
A>Другое дело, что чрезмерное использование синглтона вредно, как впрочем и чрезмерное использование чего угодно.
Его использование вобще всегда вредно.
Другое дело что этот вред не всегда сразу бросается в глаза но рано или поздно обязательно всплывает.
A>вобщем я за решения принимаемые исходя из контекста задачи, а не из идеологии.
А мне еще ни разу не попадался контекст где синглетон давал бы хоть что-то и во всех контекстах которые я анализировал он создавал проблемы.
A>Никто ведь не закладывает возможность двух принт-спулеров, потому что такое никогда не может понадобиться. Совсем никогда. Это даже не overkill, с расчётом на слетлое будущее, это абсолютное непонимание предметной области. Всё равно как выделить некоторый участок мозга на случай если вдруг родится человек с тремя глазами.
Завязывай с демогогией. Со мной не проходит.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
A>>вобщем я за решения принимаемые исходя из контекста задачи, а не из идеологии. WH>А мне еще ни разу не попадался контекст где синглетон давал бы хоть что-то и во всех контекстах которые я анализировал он создавал проблемы.
У тебя, насколько я понял, убогая система логгирования, невпихуемая в один объект. Он бы и был синглтоном, например.
A>>Никто ведь не закладывает возможность двух принт-спулеров, потому что такое никогда не может понадобиться. Совсем никогда. Это даже не overkill, с расчётом на слетлое будущее, это абсолютное непонимание предметной области. Всё равно как выделить некоторый участок мозга на случай если вдруг родится человек с тремя глазами. WH>Завязывай с демогогией. Со мной не проходит.
Демагогию начал ты, заявив, что могут понадобиться два принт-спулера.
Здравствуйте, adontz, Вы писали:
A>У тебя, насколько я понял, убогая система логгирования, невпихуемая в один объект. Он бы и был синглтоном, например.
Конечно конечно... ты тут один де'Артаньян, а все остальные...
Верь в это.
Да и не логгером единым...
A>Демагогию начал ты, заявив, что могут понадобиться два принт-спулера.
А что нет?
Ты в этом так уверен?
Можешь доказать?
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
A>>У тебя, насколько я понял, убогая система логгирования, невпихуемая в один объект. Он бы и был синглтоном, например. WH>Конечно конечно... ты тут один де'Артаньян, а все остальные... WH>Верь в это. WH>Да и не логгером единым...
Вообще-то, разработчиком того же log4net являюсь не я. Так что аргумент, мягко говоря, мимо кассы. Правда, log4net не является системой журналирования с очень развитой фильтрацией, но всё же как пример известной, широко применяемой библиотеки, которую написал не я, сойдёт
A>>Демагогию начал ты, заявив, что могут понадобиться два принт-спулера. WH>А что нет? WH>Ты в этом так уверен? WH>Можешь доказать?
Я абсолютно уверен что на одном компьютере не могут быть одновременно запущенны, корректно функционировать и не знать друг о друге два принт-спулера, два планировщика задач, два и более любых других однотипных сервиса, управляющих одними и теми же аппаратными ресурсами компьютера.
Твой подход заключатся в том, чтобы понасоздавать каждому принтеру по персональному принт-спулеру и разруливать всё внешними механизмами, дублирующими внутрение. Что же тут хорошего? Логгер, принт-спулер, и т.д. должен быть один. То, что часть сообщений пишется в один файл, а часть в другой, то, что часть документов печатается на одном принтере, а часть на другом — это внутренние настройки и их функциональность неправильно дублировать создавая по несколько спулеров, логеров и т.д. Неправильно потому что дублировать что-либо (речь, конечно, не о повышении отказоустойчивости) неправильно по сути своей. Если тебе надо записать лог, то просто пошли сообщение и не думай куда его послать и как сконфигурированно то, куда я его послал. Это же основная идеология инкапсуляции, а ты распотрошил логгер, а теперь утверждаешь, что синглтон из него плохой. Да из него и логгер вобщем-то теперь уже плохой.
Здравствуйте, adontz, Вы писали:
A>Вообще-то, разработчиком того же log4net являюсь не я. Так что аргумент, мягко говоря, мимо кассы. Правда, log4net не является системой журналирования с очень развитой фильтрацией, но всё же как пример известной, широко применяемой библиотеки, которую написал не я, сойдёт
От того что кто-то чего-то както-то написал ничего не следует.
A>Я абсолютно уверен что на одном компьютере не могут быть одновременно запущенны, корректно функционировать и не знать друг о друге два принт-спулера,
Почему? A>два планировщика задач,
Правда?
А ты знаешь что есть системы где по планировщику на ядро?
А у меня есть демон у которого просто по планировщику на поток ОС и в каждом потоке ОС есть куча потоков уровня пользователя...
A>два и более любых других однотипных сервиса, управляющих одними и теми же аппаратными ресурсами компьютера.
Угу... верь в это.
A>Твой подход заключатся в том, чтобы понасоздавать каждому принтеру по персональному принт-спулеру и разруливать всё внешними механизмами, дублирующими внутрение.
Какие внутренние?
A>Что же тут хорошего?
А чего тут плохого?
A>Логгер, принт-спулер, и т.д. должен быть один.
Кому должен?
A>То, что часть сообщений пишется в один файл, а часть в другой, то, что часть документов печатается на одном принтере, а часть на другом — это внутренние настройки и их функциональность неправильно дублировать создавая по несколько спулеров, логеров и т.д.
Почему? Уж не по тому ли что ты в это веришь?
A>Неправильно потому что дублировать что-либо (речь, конечно, не о повышении отказоустойчивости) неправильно по сути своей.
Где дублирование?
A>Если тебе надо записать лог, то просто пошли сообщение и не думай куда его послать и как сконфигурированно то, куда я его послал.
Да я и не думаю.
A>Это же основная идеология инкапсуляции, а ты распотрошил логгер, а теперь утверждаешь, что синглтон из него плохой. Да из него и логгер вобщем-то теперь уже плохой.
Верь в это.
Кстати ты постоянно пытаешься забыть что есть масса других сервисов при реализации которых так просто стрелки (типа так все делают) не перевести.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Почему? A>>два планировщика задач, WH>Правда? WH>А ты знаешь что есть системы где по планировщику на ядро? WH>А у меня есть демон у которого просто по планировщику на поток ОС и в каждом потоке ОС есть куча потоков уровня пользователя... A>>два и более любых других однотипных сервиса, управляющих одними и теми же аппаратными ресурсами компьютера. WH>Угу... верь в это.
Ты случайно пропустил "ничего не знающих друг о друге" или есть основания подозревать тебя в использовании грязных приёмов?
A>>Твой подход заключатся в том, чтобы понасоздавать каждому принтеру по персональному принт-спулеру и разруливать всё внешними механизмами, дублирующими внутрение. WH>Какие внутренние?
Те внутренние, которые уже есть в принт-спулере, позволяют ему работать с множеством принтеров, и не используюстя тобой, потому что ты готов дублировать код ради непонятной, но несомненно важной для тебя, идеологии. Хотя, на самом деле, надо было просто приглядется к спулеру и понять что он может и что, учитывая его возможности, второй никогда не может понадобится. Кстати создавая несколько спулеров ты неявно делаешь их зависисмыми, так как раньше спулер сам решал как распределять ресурсы и т.п., а теперь ты вынужден получать список принтеров, назначать им спулеры, следить чтобы каждый прнтер получил по спулеру и т.п. Налицо бессмысленное усложнение.
A>>То, что часть сообщений пишется в один файл, а часть в другой, то, что часть документов печатается на одном принтере, а часть на другом — это внутренние настройки и их функциональность неправильно дублировать создавая по несколько спулеров, логеров и т.д. WH>Почему? Уж не по тому ли что ты в это веришь?
Потому что куда и как пишутся журналы это дело системы журналирования, а не приложения отсылающего сообщения. Если понадобится писатьв другой файл, то мы оба поменяем настройки, а если придётся часть сообщений дублировать в syslog, то я как раз поменяю конфиг, а тебе писать и писать...
A>>Неправильно потому что дублировать что-либо (речь, конечно, не о повышении отказоустойчивости) неправильно по сути своей. WH>Где дублирование?
Система журналирования (нормальная) и так умеет делать то, что ты эмулируешь создавая два экземпляра логгера с разными настройками.
WH>Кстати ты постоянно пытаешься забыть что есть масса других сервисов при реализации которых так просто стрелки (типа так все делают) не перевести.
Журналирование это простой и понятный большинству пример. Я в принципе могу привести другие примеры, но они могут быть кому-то непонятны и от того наша, публичная заметь, дискуссия потеряет ценность для аудитории.
Здравствуйте, adontz, Вы писали:
A>Те внутренние, которые уже есть в принт-спулере, позволяют ему работать с множеством принтеров, и не используюстя тобой, потому что ты готов дублировать код ради непонятной, но несомненно важной для тебя, идеологии.
Откуда они там есть?
Правильно какойто любитель синглетонов понапихал...
A>Хотя, на самом деле, надо было просто приглядется к спулеру и понять что он может и что, учитывая его возможности, второй никогда не может понадобится. Кстати создавая несколько спулеров ты неявно делаешь их зависисмыми, так как раньше спулер сам решал как распределять ресурсы и т.п., а теперь ты вынужден получать список принтеров, назначать им спулеры, следить чтобы каждый прнтер получил по спулеру и т.п.
Нам по любому нужно сказать на каком принтере печатать...
A>Налицо бессмысленное усложнение.
Где?
A>Потому что куда и как пишутся журналы это дело системы журналирования, а не приложения отсылающего сообщения. Если понадобится писатьв другой файл, то мы оба поменяем настройки, а если придётся часть сообщений дублировать в syslog, то я как раз поменяю конфиг, а тебе писать и писать...
Нефига подобного.
Это ты придумал.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
A>>Те внутренние, которые уже есть в принт-спулере, позволяют ему работать с множеством принтеров, и не используюстя тобой, потому что ты готов дублировать код ради непонятной, но несомненно важной для тебя, идеологии. WH>Откуда они там есть?
А какая разница? Важно, что функциональность уже есть, а откуда она там взялась не важно.
WH>Правильно какойто любитель синглетонов понапихал...
Это перпендикуряно синглтонам.
WH>Нам по любому нужно сказать на каком принтере печатать...
А вот и фиг. Ты сейчас мало того что переиспользовал спулеры, так ещё и жёстко забил сценарий использования, гд принтер жёстко задаётся. Я вполне могу захотеть печатать (и это поддерживается в реальной жизни, это не фантазии!) на любом свободном принтере. То есть понятие "свободный принтер" перестаёт быть внутренним для спулера и наружу (непонятно зачем) выносятся все детали реализации очереди печати. Я могу захотеть печатать на любом свободном принтере в котором есть непустой лоток для листов А3. Это всё спулер уже умеет, но ты решил эту функциональность продублировать. Вот это и есть дублирование и усложнение.
A>>Потому что куда и как пишутся журналы это дело системы журналирования, а не приложения отсылающего сообщения. Если понадобится писатьв другой файл, то мы оба поменяем настройки, а если придётся часть сообщений дублировать в syslog, то я как раз поменяю конфиг, а тебе писать и писать... WH>Нефига подобного. WH>Это ты придумал.
Это реалия жизни. Спроси у любого админа, как ему удобнее работать с журналами и их конфигами.