Главная

7 основных шаблонов проектирования программного обеспечения

Используй паттерны, чтобы не изобретать велосипед.

Поделиться:
 

30+

Данная статья является ознакомительной. Если вы хотите более углубленно изучить шаблоны проектирования ПО, то рекомендую воспользоваться книгой «Software Design Patterns: Best Practices for Developers» от C.H. Афзал, ветерана программирования с многолетним опытом работы в таких компаниях, как NetflixMicrosoft и Oracle. Многое из приведенного ниже — это обобщенная версия данной книги.

Почему я выбрал именно эту тему для статьи?

В последнее время шаблоны проектирования стали предметом дискуссий в мире программирования. Некоторые люди утверждают, что из-за «чрезмерного использования» шаблонов проектирования, код становится более сложным и менее читабельным.

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

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

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

Основные шаблоны проектирования

Singleton

Шаблон Singleton используется для ограничения создания экземпляра класса только одним объектом. Это полезно, когда нужен один (и только один) объект, чтобы координировать действия в системе. Есть несколько примеров, когда есть потребность исключительно в одном экземпляре класса. Сюда следует включать кеши, пулы потоков и реестры.

Инициализация объекта класса – это тривиальная задача, но можем ли мы гарантировать, что будет создан только один объект? Ответ заключается в том, чтобы сделать конструктор «закрытым» для класса, который мы намерены определить как одиночный. Таким образом, только члены класса могут получить доступ к приватному конструктору.

Важное замечание: можно создать подкласс Singleton, сделав конструктор защищенным, а не приватным. В некоторых обстоятельствах это самый подходящий вариант. Один из подходов, применяемых в таких ситуациях, заключается в создании регистра подклассов Singleton, и метода getInstance, который принимает параметр или использует переменную окружения для возврата нужного синглтона. Затем реестр поддерживает сопоставление имен строк с одноэлементными объектами, к которым можно обращаться по мере необходимости.

Фабричный метод

Обычная фабрика производит товары; фабрика в программировании производит объекты. Более того, это делается без указания определенного класса создаваемого объекта. Объекты создаются путем вызова метода фабрики вместо вызова конструктора.

Обычно создание объектов в Java происходит примерно так:

SomeClass someClassObject = new SomeClass();

Проблема вышеупомянутого подхода состоит в том, что код, использующий объект SomeClass, становится зависимым от конкретной реализации SomeClass. Нет ничего плохого в том, чтобы использовать new для создания новых объектов, но в таком случае код тесно связан с конкретной реализацией класса, что иногда создает ряд сложностей.

Стратегия (Strategy)

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

Наблюдатель(Observer)

Этот шаблон являет собой зависимость «один ко многим» между объектами, поэтому, когда один объект изменяет состояние, все его зависимые элементы уведомляются об этом. Обычно это делается путем вызова одного из их методов.

Для упрощения подумайте о том, что происходит, когда вы подписываетесь на кого-то в Twitter. По сути, вы просите Twitter отправлять вам (наблюдателю) сообщения о человеке (теме), на которого вы подписались.

Шаблон состоит из двух действующих лиц: наблюдателя, который интересуется обновлениями, и субъекта, который генерирует обновления.

Субъект может иметь много наблюдателей и иметь связь «один ко многим». Тем не менее, наблюдатель также может подписаться на обновления других. К примеру, вы можете подписаться на новостную ленту какой-то страницы Facebook, которая, в нашем случае, будет называться субъектом, и всякий раз, когда на странице появится новое сообщение, вы это увидите.

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

Строитель(Builder)

Как, наверное, уже понятно из названия, шаблон строитель используется для построения объектов. Иногда объекты, которые мы создаем, могут быть сложными, состоять из нескольких подобъектов или нуждаться в сложном процессе создания. Создание сложных объектов можно упростить с помощью шаблона строителя. Составной объект — это продукт шаблона строитель.

Важное замечание: Шаблон строитель может показаться похожим на шаблон «абстрактной фабрики», но есть одно отличие и оно состоит в том, что шаблон строитель создает объект шаг за шагом, тогда как шаблон «абстрактной фабрики» сразу возвращает объект.

Адаптер

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

Если у вас есть два приложения, одно из которых выводит выходные данные в виде XML, а другое требует ввода JSON, то вам потребуется адаптер между ними, чтобы они работали правильно.

Состояние (State)

Шаблон State инкапсулирует различные состояния, в которых может находиться программа, и позволяет объекту изменять свое поведение в зависимости от состояния.

Программа или контекст, как это чаще называют, может совершать некие действия, которые вводят ее в разные состояния. Без использования данного шаблона код становится негибким и полон условий if-else.

Что дальше?

Я настоятельно рекомендую вам ознакомиться с книгой Software Design Patterns: Best Practices for Developers. С помощью нее вы не только отменно выучите теорию, но и сможете глубоко погрузиться в реальные проблемы, поняв практические решения на реальных примерах.

Спасибо!

30+