Skip to content

Hexlet/patterns

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Шаблоны проектирования

Сборник идиом и шаблонов проектирования с примерами на динамических языках. Основной упор делается на сути, на том, какая проблема решается. Каждый шаблон имеет множество вариантов реализации, что отражено в примерах.

Структура репозитория устроена так, что в папке content содержится список папок соответствующих паттернам. Внутри README.md с общим описанием шаблона и папки по языкам, например, javascript. Внутри папки с языком снова папки. Каждая из них - реализация паттерна в конкретной ситуации или конкретным способом.

В тех ситуациях, когда надо приводить пример в общем описании, он приводится на JavaScript.

Лирика

Шаблон проектирования (паттерн) - подходы к решению типовых задач проектирования.

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

Ключевое при работе с шаблонами - не запомнить конкретную реализацию паттерна для вашего языка, а понять проблему, в рамках которой появилось данное решение. Другими словами, нужно понимать, что паттерны - это не причина, а следствие. Классика культа карго выглядит так: программист смотрит на свой код и думает "куда мне применить вот этот паттерн".

Шаблоны проектирования - не законы физики, придуманные учёными в стенах университетов. Большинство шаблонов постоянно переизобретается разработчиками в разных уголках света. Причём не все из них вообще слышали словосочетание "паттерны программирования". Паттернов существует огромное количество и постоянно придумываются новые. Они относятся не только к коду. Например, существуют паттерны для работы с базами данных, с распределёнными системами, некоторые специфичны для конкретных языков, другие можно применять вообще почти для всего (например, фасад).

Многие шаблоны проектирования (особенно из книги GoF) с технической точки зрения сводятся к полиморфизму подтипов. В результате снижается цикломатическая сложность кода и он становится проще, но при этом часто многословнее. Реализация подобных паттернов нередко приводит к идентичному коду, и у программистов возникает вопрос, а почему это два разных паттерна, если код и там и там практически одинаковый (или одинаковый)? Все дело в семантике (смысле). За каждым паттерном стоит смысл, который понимать важнее, чем запомнить диаграмму классов. К тому же данные диаграммы применимы только для тех языков, для которых их делали. В динамике всё проще.

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

Плохая абстракция хуже дублирования кода

Не забывайте, что не бывает бесплатного сыра. О паттернах принято говорить как об избавлении от всех проблем, но это не так. Любое архитектурное решение делает систему гибкой в одном направлении, но связывает в другом. Пока развитие кода идет в сторону гибкого направления, всё будет хорошо, но как только изменятся требования, может оказаться, что ваше решение никуда не годится. Решайте проблемы по мере их поступления, только так можно научиться чему-то. Написать хорошо заранее невозможно, это миф. Ваши главные друзья: тесты, рефлексия и непрерывный рефакторинг (небольшими шагами).

Модульность

Хотя типичное определение модуля звучит как "функциональность выделяется в модуль", оно не отражает сути, что приводит к подмене понятий. Разбиение программы на модули не делает её модульной. Модульность в программировании - это малое количество связей между модулями и отсутствие циклов. Под циклическими связями понимается ситуация, в которой группа модулей зависит друг от друга так, что в группе не существует модуля, который не зависит от других модулей группы. Для двух модулей цикл означает то, что они зависят друг от друга и не могут существовать независимо.

Довольно известный Open-closed Principle на самом деле говорит о модульности и нисколько не специфичен для ООП стиля разработки.

Open-closed Principle

Принцип открытости-закрытости говорит о том, что в хорошо спроектированной системе, расширение функциональности происходит не за счет модификации старого кода, а за счет добавления нового. Он неразрывно связан с модульностью. Модульный код соответствует идее принципа.

Ключевые понятия

Клиент

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

Полезные ссылки