Какие знаешь виды паттернов?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Виды Design Patterns в Java
Design Patterns (паттерны проектирования) — это проверенные решения для типичных проблем в разработке ПО. Gang of Four (GOF) определили 23 паттерна, которые делятся на три основные категории: Порождающие (Creational), Структурные (Structural) и Поведенческие (Behavioral).
Категория 1: Порождающие паттерны (Creational)
Эти паттерны занимаются созданием объектов таким образом, чтобы система была независима от способа комбинирования объектов.
1.1 Singleton (Одиночка)
Singleton гарантирует, что класс имеет только один экземпляр и предоставляет глобальную точку доступа к нему.
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
// Потокобезопасный вариант (Eager initialization)
public class ThreadSafeSingleton {
private static final ThreadSafeSingleton instance = new ThreadSafeSingleton();
private ThreadSafeSingleton() {
}
public static ThreadSafeSingleton getInstance() {
return instance;
}
}
// Ленивая инициализация (Lazy initialization с синхронизацией)
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {
}
public static synchronized LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
1.2 Factory Method (Фабричный метод)
Factory Method определяет интерфейс для создания объекта, но оставляет подклассам решение о том, какой класс инстанцировать.
public interface Database {
void connect();
}
public class MySQLDatabase implements Database {
@Override
public void connect() {
System.out.println("Connected to MySQL");
}
}
public class PostgresDatabase implements Database {
@Override
public void connect() {
System.out.println("Connected to PostgreSQL");
}
}
public abstract class DatabaseFactory {
public abstract Database createDatabase();
public void initialize() {
Database db = createDatabase();
db.connect();
}
}
public class MySQLFactory extends DatabaseFactory {
@Override
public Database createDatabase() {
return new MySQLDatabase();
}
}
public class PostgresFactory extends DatabaseFactory {
@Override
public Database createDatabase() {
return new PostgresDatabase();
}
}
1.3 Abstract Factory (Абстрактная фабрика)
Abstract Factory предоставляет интерфейс для создания семейств связанных объектов без указания их конкретных классов.
public interface Button {
void paint();
}
public interface Checkbox {
void paint();
}
public interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
}
public class WindowsButton implements Button {
@Override
public void paint() {
System.out.println("Rendering Windows Button");
}
}
public class MacButton implements Button {
@Override
public void paint() {
System.out.println("Rendering Mac Button");
}
}
public class WindowsFactory implements GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public Checkbox createCheckbox() {
return new WindowsCheckbox();
}
}
1.4 Builder (Строитель)
Builder позволяет строить сложный объект пошагово. Отделяет конструирование объекта от его представления.
public class Person {
private String name;
private int age;
private String email;
private String phone;
public static class Builder {
private String name;
private int age;
private String email;
private String phone;
public Builder name(String name) {
this.name = name;
return this;
}
public Builder age(int age) {
this.age = age;
return this;
}
public Builder email(String email) {
this.email = email;
return this;
}
public Builder phone(String phone) {
this.phone = phone;
return this;
}
public Person build() {
Person person = new Person();
person.name = this.name;
person.age = this.age;
person.email = this.email;
person.phone = this.phone;
return person;
}
}
private Person() {
}
}
// Использование
Person person = new Person.Builder()
.name("John")
.age(30)
.email("john@example.com")
.build();
1.5 Prototype (Прототип)
Prototype позволяет создавать новые объекты на основе прототипа существующего объекта, без зависимости от их классов.
public class Shape implements Cloneable {
private String type;
private int x, y;
public Shape(String type, int x, int y) {
this.type = type;
this.x = x;
this.y = y;
}
@Override
public Shape clone() throws CloneNotSupportedException {
return (Shape) super.clone();
}
@Override
public String toString() {
return "Shape{" + type + ", (" + x + "," + y + ")" + "}";
}
}
// Использование
Shape original = new Shape("Circle", 10, 20);
Shape clone = original.clone();
Категория 2: Структурные паттерны (Structural)
Эти паттерны помогают составлять объекты и классы в более крупные структуры.
2.1 Adapter (Адаптер)
Adapter преобразует интерфейс класса в другой интерфейс, который используют клиенты.
public interface EuropeanPlug {
void useEuropeanPlug();
}
public interface AmericanPlug {
void useAmericanPlug();
}
public class Adapter implements EuropeanPlug {
private AmericanPlug americanPlug;
public Adapter(AmericanPlug americanPlug) {
this.americanPlug = americanPlug;
}
@Override
public void useEuropeanPlug() {
americanPlug.useAmericanPlug();
}
}
2.2 Bridge (Мост)
Bridge разделяет абстракцию от реализации так, чтобы они могли изменяться независимо.
public interface Renderer {
void render(String content);
}
public class HtmlRenderer implements Renderer {
@Override
public void render(String content) {
System.out.println("<html>" + content + "</html>");
}
}
public class Document {
protected Renderer renderer;
public Document(Renderer renderer) {
this.renderer = renderer;
}
public void display(String content) {
renderer.render(content);
}
}
2.3 Composite (Компоновщик)
Composite позволяет составлять объекты в древовидные структуры для представления иерархий части-целое.
public abstract class Component {
public void operation() {}
public void add(Component component) {}
public void remove(Component component) {}
}
public class Leaf extends Component {
@Override
public void operation() {
System.out.println("Leaf operation");
}
}
public class Composite extends Component {
private List<Component> children = new ArrayList<>();
@Override
public void operation() {
System.out.println("Composite operation");
for (Component child : children) {
child.operation();
}
}
@Override
public void add(Component component) {
children.add(component);
}
@Override
public void remove(Component component) {
children.remove(component);
}
}
2.4 Decorator (Декоратор)
Decorator присоединяет к объекту дополнительные обязанности динамически.
public interface Component {
String operation();
}
public class ConcreteComponent implements Component {
@Override
public String operation() {
return "ConcreteComponent";
}
}
public abstract class Decorator implements Component {
protected Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public String operation() {
return component.operation();
}
}
public class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}
@Override
public String operation() {
return super.operation() + " + ConcreteDecorator";
}
}
2.5 Facade (Фасад)
Facade предоставляет единый упрощённый интерфейс к сложной системе классов.
public class Subsystem1 {
public void operation1() {
System.out.println("Subsystem 1");
}
}
public class Subsystem2 {
public void operation2() {
System.out.println("Subsystem 2");
}
}
public class Facade {
private Subsystem1 subsystem1;
private Subsystem2 subsystem2;
public Facade() {
this.subsystem1 = new Subsystem1();
this.subsystem2 = new Subsystem2();
}
public void operation() {
subsystem1.operation1();
subsystem2.operation2();
}
}
Категория 3: Поведенческие паттерны (Behavioral)
Эти паттерны имеют дело с объектным сотрудничеством и распределением обязанностей между объектами.
3.1 Strategy (Стратегия)
Strategy определяет семейство алгоритмов, инкапсулирует каждый из них и делает их взаимозаменяемыми.
public interface PaymentStrategy {
void pay(double amount);
}
public class CreditCardPayment implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("Paying " + amount + " with credit card");
}
}
public class PayPalPayment implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("Paying " + amount + " with PayPal");
}
}
public class ShoppingCart {
private PaymentStrategy strategy;
public void setPaymentStrategy(PaymentStrategy strategy) {
this.strategy = strategy;
}
public void checkout(double amount) {
strategy.pay(amount);
}
}
3.2 Observer (Наблюдатель)
Observer определяет зависимость один-ко-многим между объектами таким образом, что при изменении состояния одного объекта все зависящие от него объекты оповещаются автоматически.
public interface Observer {
void update(String event);
}
public class Subject {
private List<Observer> observers = new ArrayList<>();
public void attach(Observer observer) {
observers.add(observer);
}
public void detach(Observer observer) {
observers.remove(observer);
}
public void notifyObservers(String event) {
for (Observer observer : observers) {
observer.update(event);
}
}
}
public class ConcreteObserver implements Observer {
@Override
public void update(String event) {
System.out.println("Received event: " + event);
}
}
3.3 Command (Команда)
Command инкапсулирует запрос как объект, позволяя параметризовать клиентов с различными запросами.
public interface Command {
void execute();
}
public class Light {
public void on() {
System.out.println("Light is on");
}
public void off() {
System.out.println("Light is off");
}
}
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.on();
}
}
public class RemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}
3.4 Template Method (Шаблонный метод)
Template Method определяет скелет алгоритма в методе, оставляя подклассам переопределение отдельных шагов.
public abstract class DataProcessor {
public final void process() {
readData();
parseData();
saveData();
}
protected abstract void readData();
protected abstract void parseData();
protected abstract void saveData();
}
public class CSVProcessor extends DataProcessor {
@Override
protected void readData() {
System.out.println("Reading CSV");
}
@Override
protected void parseData() {
System.out.println("Parsing CSV");
}
@Override
protected void saveData() {
System.out.println("Saving CSV");
}
}
3.5 State (Состояние)
State позволяет объекту изменять своё поведение в зависимости от своего состояния.
public interface State {
void handle(Context context);
}
public class ConcreteStateA implements State {
@Override
public void handle(Context context) {
System.out.println("State A");
context.setState(new ConcreteStateB());
}
}
public class Context {
private State state;
public void setState(State state) {
this.state = state;
}
public void request() {
state.handle(this);
}
}
Таблица всех 23 паттернов GOF
| Порождающие | Структурные | Поведенческие |
|---|---|---|
| Singleton | Adapter | Chain of Responsibility |
| Factory Method | Bridge | Command |
| Abstract Factory | Composite | Interpreter |
| Builder | Decorator | Iterator |
| Prototype | Facade | Mediator |
| Flyweight | Memento | |
| Proxy | Observer | |
| State | ||
| Strategy | ||
| Template Method | ||
| Visitor |
Рекомендации
- Изучите паттерны постепенно через практику
- Не переусложняйте код, используя паттерны без необходимости
- Используйте паттерны для решения известных проблем
- Комбинируйте паттерны для большей гибкости
- Spring Framework использует множество паттернов (Singleton, Factory, Observer, Proxy и т.д.)