Паттерны проектирования - шаблоны проектирования программного обеспечения.
Определяет общий интерфейс для создания объектов в superclass, позволяя подклассам изменять тип создаваемых объектов.
Реализация: метод create(String type) возвращает нужный подкласс
Пример: parsers файлов(.json, .xml), отправка уведомлений
class A {
public void doSomething() {
Foo f = makeFoo();
f.whatever();
}
protected Foo makeFoo() {
return new RegularFoo();
}
}
class B extends A {
protected Foo makeFoo() {
//subclass is overriding the factory method
//to return something different
return new SpecialFoo();
}
}
Позволяет создавать семейства связанных объектов, не привязываясь к конкретным классам создаваемых объектов.
Реализация: интерфейс для создания связанных объектов без указания их классов.
Пример: UI-темы (тёмная/светлая), фабрики виджетов операционной системы.
class A {
private Factory factory;
public A(Factory factory) {
this.factory = factory;
}
public void doSomething() {
//The concrete class of "f" depends on the concrete class
//of the factory passed into the constructor. If you provide a
//different factory, you get a different Foo object.
Foo f = factory.makeFoo();
f.whatever();
}
}
interface Factory {
Foo makeFoo();
Bar makeBar();
Aycufcn makeAmbiguousYetCommonlyUsedFakeClassName();
}
//need to make concrete factories that implement the "Factory" interface here
Позволяет создавать сложные объекты пошагово. Убирает необходимость создавать множество конструкторов.
Реализация: цепочка вызовов .set() + .build().
Пример: создание сложных объектов, например HTTP-запросов.
Позволяет копировать объекты, не вдаваясь в подробности их реализации.
\Реализация: клонирование существующего объекта через .clone().
Пример: игровые персонажи, шаблоны документов, клоны интерфейсов.
Гарантирует, что у класса есть только один экземпляр, и предоставляет к нему глобальную точку доступа. Есть 2 варианта создания 1 - Lazy(создание при обращении), 2 - Eager(жадный, создание при старте приложения).
Реализация: статический экземпляр + приватный конструктор.
Пример: логгер, менеджер конфигурации, пул подключений к БД.
class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
Изменение интерфейса. Позволяет объектам с несовместимыми интерфейсами работать вместе.
Реализация: класс-обёртка, преобразующий интерфейс.
Пример: интеграция с легаси API, InputStreamReader.
Разделяет один или несколько классов на две отдельные иерархии — абстракцию и реализацию, позволяя изменять их независимо друг от друга.
Реализация: разделение абстракции и реализации.
Пример: представление UI → движок отрисовки (SVG, Canvas и т.д.).
Позволяет сгруппировать множество объектов в древовидную структуру, а затем работать с ней так, как будто это единичный объект.
Реализация: древовидная структура, где элементы и группы обрабатываются одинаково.
Пример: иерархия файлов и папок, UI-компоненты.
Позволяет вместить большее количество объектов в отведённую оперативную память. Легковес экономит память, разделяя общее состояние объектов между собой, вместо хранения одинаковых данных в каждом объекте.
Реализация: повторное использование объектов с общим внутренним состоянием.
Пример: глифы шрифта, иконки интерфейса, текстуры в играх.
Предоставляет простой интерфейс к сложной системе class/library/framework.
Реализация: один класс делегирует вызовы нескольким подсистемам.
Пример: java.util.logging, фасад медиаплеера.
Добавить новую функциональность(не меняя базовый интерфейс). Добавлять объектам новую функциональность, о борачивая их в полезные «обёртки». Гибкая альтернатива практике создания подклассов с целью расширения функциональности. Примеры:InputStream, FileInputStream, BufferedReader и тд. Способствует SOLID - Open Close.
Реализация: обёртка над объектом + добавление поведения на лету
Пример: логгирование, сжатие, кэширование
Контроль доступа, защита, управление ресурсами. Эти объекты перехватывают вызовы к оригинальному объекту, позволяя сделать что-то до или после передачи вызова оригиналу.
Реализация: обёртка над реальным объектом для контроля доступа или производительности.
Пример: ленивая загрузка, контроль доступа, удалённые прокси.
Позволяет передавать запросы последовательно по цепочке обработчиков. Каждый последующий обработчик решает, может ли он обработать запрос сам и стоит ли передавать запрос дальше по цепи.
Реализация: каждый обработчик решает — обработать или передать дальше.
Пример: эскалация тикетов в техподдержке, всплытие событий (event bubbling).
Превращает запросы в объекты, позволяя передавать их как аргументы при вызове методов, ставить запросы в очередь, логировать их, а также поддерживать отмену операций.
Реализация: инкапсуляция действия в объект с методом execute().
Пример: Undo/Redo, обработка нажатий кнопок.
Даёт возможность последовательно обходить элементы составных объектов, не раскрывая их внутреннего представления.
Позволяет уменьшить связанность множества классов между собой, благодаря перемещению этих связей в один класс-посредник.
Реализация: центральный объект управляет взаимодействием компонентов.
Пример: менеджер чата, валидация форм в UI.
Позволяет сохранять и восстанавливать прошлые состояния объектов, не раскрывая подробностей их реализации.
Реализация: сохранение и восстановление внутреннего состояния объекта.
Пример: история изменений, снапшоты состояния в текстовом редакторе.
Создаёт механизм подписки, позволяющий одним объектам следить и реагировать на события, происходящие в других объектах.
Реализация: список подписчиков + цикл notifyAll().
Пример: система событий, UI-слушатели, подписки на YouTube.
Позволяет объектам менять поведение в зависимости от своего состояния. Извне создаётся впечатление, что изменился класс объекта.
Реализация: поведение определяется текущим объектом состояния.
Пример: состояния медиаплеера — воспроизведение/пауза/стоп.
Определяет семейство схожих алгоритмов и помещает каждый из них в собственный класс, после чего алгоритмы можно взаимозаменять прямо во время исполнения программы.
Реализация: интерфейс + метод setStrategy()
Пример: алгоритмы сортировки, платёжные процессоры
Скелет алгоритма, перекладывая ответственность за некоторые его шаги на подклассы. Паттерн позволяет подклассам переопределять шаги алгоритма, не меняя его общей структуры.
Реализация: базовый класс задаёт общий алгоритм, подклассы переопределяют шаги.
Пример: обработка онлайн-заказа — оплата → подтверждение → доставка.
Позволяет добавлять в программу новые операции, не изменяя классы объектов, над которыми эти операции могут выполняться.
Реализация: внешний класс выполняет операции над элементами структуры
Пример: обход файловой системы, обработка AST