И вот, наконец, сложилось. Статья о принципах модульного проектирования. Как сделать так, чтобы модуль можно было переиспользовать. Читайте: http://www.skipy.ru/architecture/module_design.html.
Обсуждение – в этой теме.
Очередная статья родилась. Времени на нее я потратил чуть не четыре месяца – было много работы, да и статья обширная, иллюстративных примеров…
Еще одна статья, практически из серии «ликбез»: «Вавилонское столпотворение. Часть 4. Проза жизни: компиляция и вывод в консоль».…
Еще одна статья вышла. На этот раз - про синхронизацию пользовательского интерфейса. Про выполнение длительных задач так, чтобы не блокировать весь…
Очередная статья родилась. Времени на нее я потратил чуть не четыре месяца – было много работы, да и статья обширная, иллюстративных примеров…
Еще одна статья, практически из серии «ликбез»: «Вавилонское столпотворение. Часть 4. Проза жизни: компиляция и вывод в консоль».…
Еще одна статья вышла. На этот раз - про синхронизацию пользовательского интерфейса. Про выполнение длительных задач так, чтобы не блокировать весь…
September 14 2010, 07:49:53 UTC 10 years ago
September 14 2010, 15:07:23 UTC 10 years ago
З.Ы. По-моему запятая в названии статьи лишняя.
September 15 2010, 06:00:34 UTC 10 years ago
В своей статье об IoC Мартин Фаулер привел хорошую аналогию с т.н. «голливудским принципом» – «не звоните нам, мы вам позвоним сами». Саму статью можно прочитать вот тут: http://martinfowler.com/bliki/InversionOfControl.html.
В дополнение приведу еще один пример IoC из Java, не связанный явно с DI.
Возьмем обычную сериализацию. Как Вы знаете, существует два способа реализации - использование Serializable и Externalizable. Начнем со второго.
Что происходит при обработке Externalizable? Объекту дают поток и говорят - на, родной, пишись! И объект сам пишет свои данные. И точно так же при чтении, создается пустой экземпляр, ему дается поток и говорится - на, родной, читайся. И объект сам читает свои данные.
А что происходит в случае Serializable? Объект сам ничего не делает. Он попадает в механизм, который разбирает его по косточкам, вытаскивает из него все данные и записывает в поток. И точно так же при чтении - внешний механизм читает данные из потока и прописывает их в объект. В этом случае сам объект не является активным действующим лицом - все операции производятся над ним кем-то. IoC в чистом виде.
На самом деле, если копнуть глубже - тут наблюдается сходство с DI. И в том, и в другом случаях в определенное поле объекта пишется определенное значение. Это может быть ссылка на объект, это может быть прочитанное число. Не суть принципиально, и то и другое - IoC. Просто когда мы говорим об объектах, мы не думаем о ссылках, - это ниже того уровня абстракции, на котором мы мыслим в данный момент. Скажем так, запись ссылки - это физическая реализация установки зависимости. А на более высоком уровне абстракции мы говорим о DI. То есть можно сказать, что IoC лежит в основе принципа реализации DI, но им не ограничивается.
September 16 2010, 01:26:48 UTC 10 years ago
September 15 2010, 06:00:56 UTC 10 years ago
September 15 2010, 11:21:28 UTC 10 years ago
Классики также приводят в качестве примера IoC-не-DI оконную систему управляемую событиями, т.е.
не код активно читает getKeypress(), а сама система вызывает методы кода по приходу событий от клавиатуры
September 15 2010, 19:52:53 UTC 10 years ago
Единственная проблема, которую я тут вижу -- где определять createConfigurationFromXXX. Если у нас не чисто объектный язык -- то их логично сделать top-level функциями модуля реализации. Если Java/C# -- придется завести отдельный класс со статическими методами (заодно названия станут короче).
September 16 2010, 05:59:11 UTC 10 years ago
Насчет статических функций. Я Вам советую посмотреть на классы конфигурации из Log4J. Чтобы объем оценить. Вы действительно ЭТО хотите в одну статическую функцию запихнуть? А как только начнете разбивать - в одном классе окажется куча мелких функций, одни работают со свойствами, другие с XML, третьи с аннотациями (а ведь через месяц Вам аннотации точно понадобятся, в очередном проекте!). И Вы в них мгновенно утонете.
Кроме того, статические функции противоречат принципу OCP - при необходимости добавления новой конфигурации Вам придется менять ConcreteConfiguration. А мне придется всего лишь добавить новый класс. Отдельный, ни на кого больше не влияющий.
P.S. > их логично сделать top-level функциями модуля реализации
Хочу напомнить, что я говорю про объектно-ориентированные языки. Процедурные меня не волнуют. Кстати, "отдельный класс со статическими методами" - это тоже из процедурных языков принесено.
P.P.S. Длина имен функций меня волнует еще меньше. Имя должно описывать функцию, а его длина второстепенна.
September 16 2010, 19:19:56 UTC 10 years ago
То что у них одна реализация -- отчетливо видно из определения класса AbstractConfiguration.
> Вы действительно ЭТО хотите в одну статическую функцию запихнуть?
Нет, конечно, ООП не противоречит функциональной декомпозиции.
> при необходимости добавления новой конфигурации Вам придется менять ConcreteConfiguration
1. А что мешает определять новые методы в других классах?
> Хочу напомнить, что я говорю про объектно-ориентированные языки. Если у нас объектный язык с примесью функционального (Python, OCaml, F#), то -- функции (не обязательно объявленные в одном месте)+ их передача . Если чисто объектный и логика сложная, то получаем XXXConfigurationReader.
Про Log4j: у них больше похоже на мою модель, только ConfigurationReader называется Configurator и вместо выдачи конфигурацию наружу, конфигурирует LoggerRepository.
10 years ago
Anonymous
September 20 2010, 15:42:32 UTC 10 years ago
September 21 2010, 08:02:31 UTC 10 years ago
P.S. Думаете, я до всего этого дошел сразу? Мне лет 6-7 понадобилось, чтобы только начать чувствовать такие вещи. И еще года 4 - чтобы быть способным внятно сформулировать.
Локатор сервисов
Anonymous
September 28 2010, 09:38:36 UTC 10 years ago
1)Кто отвечает за конфигурацию и заполнение локатора? Конфигурацию можно сделать в xml или аннотациях. Локатор должен их прочитать и сам себя заполнить. Так или нет?
2)В локаторе должны находиться только экземпляры зависимостей и тех кто от них зависит или что то еще?
Если делать конфигурацию аннотациями как вы написали в статье то:
3)какие параметры должны быть указаны в @Provider и @Injection?
4)как эффективно искать классы помеченные именно этими аннотациями? Не переберать же все классы из cp?
5)Где можно посмотреть пример такого локатора с аннотациями?
Изменяюсь, за такое большое кол-во вопросов, но надеюсь что вы ответите.
Re: Локатор сервисов
September 28 2010, 10:06:56 UTC 10 years ago
1. Ну, в принципе так. Лучше на XML, аннотации все-таки надо искать.
2. Да, локатор предназначен для создания дерева зависимостей. Все остальное там лишнее.
3. Дело в следующем. Если мы будем, например, ориентироваться только по имени класса - мы получим по одному экземпляру каждого типа. А если их нужно несколько? Например, DataDestination - на его базе можно сделать лог. Т.е. в модуле мы будем иметь не один экземпляр DataDestination, а два. Работа с ними идентичная, что нам и надо. А вот получение - в одном случае я могу написать, скажем, @Injection(Type.business), в другом - @Injection(Type.log). Считаем, что enum Type определен. Ну и две реализации - @Provider(DataDestination.class, Type.business) и @Provider(DataDestination.class, Type.log). Соответственно, при внедрении зависимости по классу и конкретному типу мы можем найти нужный экземпляр.
4. При старте - не надо, это долго. А вот при сборке - да. Других вариантов нет. Сканируется наш jar (только наш, а не весь classpath, что уже существенно лучше), всё, что найдено с аннотациями - собирается. Потом пишется xml, на который и будет ориентироваться локатор.
5. Ну... разве что я соберусь и напишу. :) Когда время найду.
May 8 2012, 20:07:00 UTC 8 years ago
А вот работа с локаторами описана как-то недостаточно подробно. Хотелось бы иллюстративных примеров. Хотя бы про то, как на создавать и использовать чисто локаторы. Ну, и хорошо б и конкретный пример реализации совместного использования локатора и внедрения параметров.
И статью про остальные 3 базовые принципа хорошего дизайна было бы отлично увидеть =)
October 28 2012, 00:44:26 UTC 8 years ago