В этой статье поговорим о том, что такое паттерны проектирования, какие они бывают, для чего нужны. Материал будет полезен начинающим программистам.
Паттерны — это способ построения (структуризации) программного кода специальным образом. На практике они используются программистами для того, чтобы решить какую-нибудь проблему, устранить определенную «боль» разработчика. В этом случае предполагается, что существует некоторый перечень общих формализованных проблем (а это так и есть), причем данные проблемы встречаются относительно часто. И вот здесь-то на сцену и выходят паттерны, которые как раз таки и предоставляют способы решения этих проблем.
Немного истории
Сама по себе тема паттернов не является новой. Непосредственная идея по созданию принципов, описывающих решение распространенных в программировании/проектировании ПО проблем, появилась в далеком 1994 году. Именно в этом году в свет вышла известная книга «Design Patterns: Elements of Reusable Object-Oriented Software». Работа была создана целым авторским коллективом, который иногда называют «Gang of Four» (сокращенно GoF) — «Банда четырех». На деле это опытные инженеры-разработчики, вот их имена:
- Ральф Джонсон,
- Ричард Хелм,
- Эрих Гамма,
- Джон Влиссидес.
Книга, о которой идет речь, — это первая серьезная попытка описать наиболее распространенные способы проектирования программного обеспечения. Спустя некоторое время, использование паттернов стало не прихотью разработчика, а хорошей практикой программирования.
Какова польза?
Но существует ли реальный профит от использования паттернов? При грамотном применении — безусловно. Когда вы пишете программный код, вы можете формализовать проблему в виде объектов, классов и соответствующих связей между ними. Когда проблема формализована, для ее решения останется задействовать один из существующих паттернов. Это экономит время программиста, ведь не надо изобретать велосипед и что-нибудь придумывать. Готовый pattern (способ решения) уже существует — нужно лишь правильно применить его в конкретной программе.
Важный момент — использование того либо иного паттерна практически не зависит от языка программирования, системы или интерфейса. То есть принципы применения паттернов проектирования в Java, С-шарп и прочих языках будут аналогичными.
Подведем некоторый промежуточный итог: активное использование паттернов упрощает разработку программ. Есть и другой плюс: если программист, который столкнется с чужим кодом, знает примененный паттерн проектирования и его принципы, ему будет проще понять реализацию и внести изменения в код в случае надобности.
Но у этой медали есть и другая сторона. Да, хорошая программа может подразумевать использование шаблонов проектирования. Но может и не подразумевать. А все потому, что не всегда они позволяют упрощать и улучшать программный код. То есть речь идет о том, что использовать паттерны везде и всюду, то есть применять паттерны ради самих паттернов — это явно плохая практика. Не стоит забывать, что неоправданное применение усложнит код, снизит его качество. Просто помните, что pattern ВСЕГДА должен быть оправданным — и лишь в этом случае он сможет эффективно решить проблему.
Сегодня существует очень много разных паттернов. Они решают различные вопросы, выполняют разные задачи. И действует они по-разному, поэтому их можно классифицировать по группам. В основе такой классификации и объединения в группы будут лежать поставленные цели и решаемые задачи.
Порождающие паттерны
Порождающие паттерны абстрагируют процесс инстанцирования (процесс порождения классов и объектов). Вот их список:
- Abstract Factory — «Абстрактная фабрика»;
- Builder — «Строитель»;
- Factory Method — «Фабричный метод»;
- Prototype — «Прототип»;
- Singleton — «Одиночка».
Структурные паттерны
В этой группе рассматривается, каким образом классы и объекты формируют более крупные структуры (речь идет о более сложных по характеру классах и создаваемых объектах). Перечень структурных шаблонов:
- Adapter — «Адаптер»;
- Bridge — «Мост»;
- Composite — «Компоновщик»;
- Decorator — «Декоратор»;
- Facade — «Фасад»;
- Flyweight — «Приспособленец»;
- Proxy — «Заместитель».
Поведенческие паттерны
Группа под номером 3 объединяет шаблоны, связанные с поведением. Они определяют алгоритмы взаимодействия между объектами и классами, то есть их поведение. Вот перечень наиболее популярных поведенческих паттернов:
- Chain of responsibility — «Цепочка обязанностей»;
- Command — «Команда»;
- Interpreter — «Интерпретатор»;
- Iterator — «Итератор»;
- Mediator — «Посредник»;
- Memento — «Хранитель»;
- Observer — «Наблюдатель»;
- State — «Состояние»;
- Strategy — «Стратегия»;
- Template method — «Шаблонный метод»;
- Visitor — «Посетитель».
Другие классификации
В зависимости от того, относится pattern к объектам или классам, существуют и другие классификации паттернов.
К примеру, паттерны классов описывают взаимодействие между классами с помощью наследования, причем эти отношения определяются на этапе компиляции. Вот примеры:
- Factory Method;
- Interpreter;
- Template Method;
- Adapter.
Следующая группа — это паттерны объектов, описывающие взаимодействие между объектами. Отношения такого характера возникают на стадии выполнения, следовательно, они более гибкие. Примеры:
- Abstract Factory;
- Builder;
- Prototype;
- Singleton;
- Bridge;
- Composite;
- Decorator;
- Facade;
- Flyweight;
- Proxy;
- Chain of responsibility;
- Command;
- Iterator;
- Mediator;
- Memento;
- Observer;
- State;
- Strategy;
- Visitor.
Мы перечислили лишь основные варианты, но в реальности их намного больше. Некоторые только начали использоваться, некоторые переживают пик популярности, а некоторые, наоборот, стали применяться реже.
Как сделать правильный выбор?
Прежде чем принять какое-либо решение, следует выделить используемые сущности, а также связи между этими сущностями, после чего необходимо абстрагировать сущности от конкретной ситуации. Получив некую абстрактную форму, посмотрите, вписывается ли она в какой-нибудь из существующих паттернов. К примеру, если смысл решаемой задачи заключается в создании новых объектов, то стоит обратить внимание на порождающие паттерны. Это значит, что следует взять несколько родственных шаблонов из соответствующей группы и определить, какой из них подходит в большей мере с учетом поставленной задачи.
То есть разработчику не только важно понимать смысл и назначение шаблона, но и явно представлять его абстрактную организацию, плюс возможные конкретные реализации, ведь они могут быть разными для одного и того же паттерна. С практикой, чем чаще сталкиваешься с различными реализациями, тем лучше знаешь и понимаешь непосредственный смысл шаблона. Но если вы его не понимаете, использовать его нежелательно, причем даже в том случае, если поначалу кажется, что это именно то, что необходимо именно сейчас.
Вывод прост: придерживайтесь известного принципа KISS (Keep It Simple, Stupid), то есть сохраняйте программный код простым и ясным настолько, насколько это возможно. Иначе теряется весь смысл паттернов проектирования, который заключается именно в упрощении программы.
Хотите поработать с популярными шаблонами проектирования для Java? Желаете попробовать поработать с паттернами для C#? Обратите внимание на наши продвинутые https://otus.ru/catalog/courses?categories=programming на Java и C#:
Также в Otus существует специальный курс «Архитектура и шаблоны проектирования», посвященный паттернам. Не пропустите!
По материалам https://metanit.com/.