ams

Паттерны Проектирования

Ошибочным считается восприятие паттернов проектирования как некий не набор ограничений созданных для неквалифицированных специалистов, соблюдение которого ведет к увеличению размера исходных кодов и запутыванию новичков. Наоборот, паттерны проектирования позволяют молодым специалистам немедленно погрузиться в гущу событий и получить выкристализированное знание, полученное ведущими практиками в производстве в течение многих десятилетий. Паттерны проектирования используются в таких, неотделимых от жизни обычного пользователя областях человеческой деятельности как построение АСУТП АЭС, проектирование микропроцессоров, искуственный интеллект, игровые и развлекательные системы, банковские системы, разработка операционных систем, а также применяются для построение компиляторов и всех видов фреймворков.

ПО от Google, Microsoft, Apple использует паттерны проектирования и каждый, я повторюсь, каждый, специалист несомненно должен разбираться в паттернах проектирования. Не секрет, что попасть к нам в компанию можно только хорошо изучив все паттерны проектирования. Паттерны проектирования очень нужны и полезны. Они помогут вам нанять литераторов, творческих и духовно богатых людей, которые смогут в дальнейшем строить сложные системы и описывать наш мир в терминах объектов. От этого ваши продукты будут наполнены жизнью и красотой, в отличии от сухих и ничем не примечательных программ интровертов-инженеров. Благодаря паттернам проектирования мы смогли сформировать свою команду из талантливых людей, которые видят суть программ. Паттерны проектирование — это, если хотите, метафизика Computer Science. Ведь, даже если вы думаете, что вы не используете паттерны проектирования вы все равно тем или иным образом вовлечены в шаблонное мышление.

Итак разберем более детально, что необходимо знать каждому инженеру прикладной математики, Computer Science и факультетов информатики. Все Паттерны Проектирования делятся на святую троицу: Поведенческие, Структурные и Порождающие.
Поведенческие

Обсервер или так называемый Паб/Саб. Все взрослые системы используют шину сообений. Есть специализированные продукты RabbitMQ, Redis, Tibco JMS, Fiorano, ZeroMQ, ActiveMQ, IBM WebSphere, также Pub/Sub паттер применяется повсеместно для организации событий на стороне клиента, без Pub/Sub мы не построим ну никак удобную систему ивентинга, и не верьте интровертам неквалифицированным специалистам из мира ФП, которые вам будут твердить обратное про FRP и композицию событийных стримов. Без Pub/Sub было бы невозможно построить Facebook, LinkedIn, Twitter и Google+. Pub/Sub как видно из названия сводится к двум функциям. Очень просто запомнить, как в Бейсике Peek и Poke.

pub(Message,Channel) % публикация в шину
sub(Channel,Callback) % подписаться на события шины

Чейн оф респонсибилити. Тоже очень нужный паттерн, без него было бы невозможно проектировать сложные системы. Любой фреймворк в котором есть слои (а это есть у всех), которые нужно подменять ипользуют этот паттер. IO запросы во всех операционных системах, стеки хендлеров, модель OSI, все это примеры чейн оф респонсибилити паттерн. Очень сложно запомнить как его писать. Представьте, что у вас есть список хендлеров через которые должно пройти сообщение, это могут быть фильтры или слои подсистемы авторизации. Мы будем использовать специальный псевдокод для описания сложных паттернов:

lists:foldl(fun(Module,Ctx,Args) ->
Module:Fun(Args,Ctx) end,Context,Handlers).


Команда. Этот паттерн позволяет добавлять функцинальность на лету. Наприме прислать встроить в меню вашего приложения новые комманды про которое оно не знано раньше. Благодаря тому, что вы скопируете нужеую DLL с интерфейсом ICommand, вы сможете вызвать метод Command:exec(Args). Не удивляйтесь что на псевдокоде это выглядит так просто, за этим паттерном стоит 5 классов и два интерфейса, а если учесть протокол по которому просиходит обновление кода, то и вовсе можно запутаться. Но понимание псевдокода поможет вам запомнить этот сложный и нужный паттерн.

Стейт паттерн. Это фундаментальный паттерн который позволит вам разрабатывать гибкие и понастоящему полиморфные приложения. В реальной жизнь очень часто объекты окружающего нас мира меняют свое поведение в зависимости от своего состояния. Для реализации реальных и практичных, а не неисследовательских систем вы обязательно будете использовать Стейт Паттерн. Это паттерн настолько сложный что для него не существует псевдокода для мнемонического запоминания. Его очень легко спутать с Паттерном Плагин или Паттерном Стратегия. Понимание различия этих паттернов ключ к успешной разработки приложениий.

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

Визитор. Этот паттерн чаще всего испльзуется при рендеринге данных, или алгоритме обхода сложных структур данных типа деревьев. Например представьте себе, что вам нужно отрендерить HTML или XML документ в браузере, который представляет собой иерархическую структуру. Это можно легко сделать с помощью псевдокода, который легко запомнить. Очень простой и понятный паттерн.

[ render(E) || E <- lists:flatten(Elements) ],

Момент. Этот шаблон пректирования позволит вам как в ворде сохранить документ, даже если компьютер внезапно выключится. Для этого вам в программе нужно будет реализовать одну функция save(Document).

Интерпретатор. Очень сложный паттерн, которым пользуются системные программиста для разработки компиляторов и интерпретаторов. Если ваша система использует механизм скриптования, вы должны использовать паттерн интерпретатор. Лучше всего для языков использовать BNF нотацию, вот пример описания полноценного объектно ориентированного фунционального динамически типизированного языка с макросами, квазицитированием и возможностями паралельного программирования:

program ::= message [ program ]
message ::= symbol [ «(» [ message [ «,» message ] ] «)» ]


Шаблон. Шаблон Проектирования Шаблон, или сокращенно ШПШ. Представьте себе, что вы пишете программу которую, некоторые части которой в будущем вам придется изменить или подставить. Очень удобно такие места помечать специальными символами или превращать во внешние функции, которые можно будет параметризировать, например в отличии от method(Args) вы пишете

?MODULE:method(Args).

Удобно, можно потом будет подставить модуль реализации и не переписывать программу.

Продолжение о Структурных и Порождающих, а также спецвыпуск про ORM и MVC читайте в следующих номерах.