← Назад к вопросам

Какие паттерны знаешь кроме Singleton и Factory

1.8 Middle🔥 171 комментариев
#SOLID и паттерны проектирования

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Design Patterns в Java

Кроме Singleton и Factory существует множество полезных паттернов проектирования, разделённых на три основные категории. Рассмотрю наиболее практичные для backend-разработки.

Порождающие паттерны (Creational)

Builder

Builder упрощает создание сложных объектов с множеством параметров:

public class User {
    private String name;
    private String email;
    private int age;
    private String phone;
    
    public static class Builder {
        private String name;
        private String email;
        private int age;
        private String phone;
        
        public Builder name(String name) {
            this.name = name;
            return this;
        }
        
        public Builder email(String email) {
            this.email = email;
            return this;
        }
        
        public Builder age(int age) {
            this.age = age;
            return this;
        }
        
        public User build() {
            return new User(name, email, age, phone);
        }
    }
    
    private User(String name, String email, int age, String phone) {
        this.name = name;
        this.email = email;
        this.age = age;
        this.phone = phone;
    }
}

// Использование
User user = new User.Builder()
    .name("John")
    .email("john@example.com")
    .age(30)
    .build();

Prototype

Prototype позволяет создавать объекты через клонирование:

public class Document implements Cloneable {
    private String title;
    private List<String> pages;
    
    @Override
    public Document clone() throws CloneNotSupportedException {
        Document cloned = (Document) super.clone();
        cloned.pages = new ArrayList<>(this.pages);  // Глубокое копирование
        return cloned;
    }
}

Document original = new Document("Report", pages);
Document copy = original.clone();  // Независимая копия

Структурные паттерны (Structural)

Adapter

Adapter позволяет интегрировать несовместимые интерфейсы:

// Старая система
public interface OldPaymentSystem {
    void processPayment(String accountId, double amount);
}

// Новая система
public interface NewPaymentAPI {
    void pay(String userId, BigDecimal sum);
}

// Адаптер
public class PaymentAdapter implements NewPaymentAPI {
    private OldPaymentSystem oldSystem;
    
    public PaymentAdapter(OldPaymentSystem oldSystem) {
        this.oldSystem = oldSystem;
    }
    
    @Override
    public void pay(String userId, BigDecimal sum) {
        // Преобразуем новый интерфейс в старый
        oldSystem.processPayment(userId, sum.doubleValue());
    }
}

Decorator

Decorator добавляет функциональность объекту динамически:

public interface InputStream {
    int read();
}

public class FileInputStream implements InputStream {
    // Базовая реализация
}

public class BufferedInputStream implements InputStream {
    private InputStream input;
    
    public BufferedInputStream(InputStream input) {
        this.input = input;  // Оборачиваем
    }
    
    @Override
    public int read() {
        // Добавляем буферизацию
        return input.read();
    }
}

public class CompressedInputStream implements InputStream {
    private InputStream input;
    
    public CompressedInputStream(InputStream input) {
        this.input = input;
    }
    
    @Override
    public int read() {
        // Добавляем декомпрессию
        return input.read();
    }
}

// Использование
InputStream stream = new CompressedInputStream(
    new BufferedInputStream(
        new FileInputStream()
    )
);  // Множественное обогащение функциональности

Facade

Facade упрощает работу со сложной подсистемой:

// Сложная подсистема с множеством классов
public class Database { }
public class Logger { }
public class Security { }

// Фасад
public class OrderService {
    private Database db;
    private Logger logger;
    private Security security;
    
    public void createOrder(Order order) {
        security.validateUser();
        logger.log("Creating order");
        db.save(order);
        logger.log("Order created");
    }
}

// Клиент работает только с OrderService
OrderService service = new OrderService();
service.createOrder(order);  // Простой интерфейс

Поведенческие паттерны (Behavioral)

Observer

Observer реализует подписку на изменения:

public interface EventListener {
    void update(Event event);
}

public class EventManager {
    private List<EventListener> listeners = new ArrayList<>();
    
    public void subscribe(EventListener listener) {
        listeners.add(listener);
    }
    
    public void notify(Event event) {
        for (EventListener listener : listeners) {
            listener.update(event);
        }
    }
}

public class UserRegisteredListener implements EventListener {
    @Override
    public void update(Event event) {
        System.out.println("Sending welcome email...");
    }
}

// Использование
EventManager manager = new EventManager();
manager.subscribe(new UserRegisteredListener());
manager.notify(new UserRegisteredEvent());

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 + " by credit card");
    }
}

public class PayPalPayment implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("Paying " + amount + " via PayPal");
    }
}

public class Order {
    private PaymentStrategy strategy;
    
    public void setPaymentStrategy(PaymentStrategy strategy) {
        this.strategy = strategy;
    }
    
    public void checkout(double amount) {
        strategy.pay(amount);  // Используем выбранную стратегию
    }
}

Order order = new Order();
order.setPaymentStrategy(new CreditCardPayment());
order.checkout(100);

Command

Command инкапсулирует операцию как объект:

public interface Command {
    void execute();
    void undo();
}

public class OpenFileCommand implements Command {
    private String filename;
    
    public OpenFileCommand(String filename) {
        this.filename = filename;
    }
    
    @Override
    public void execute() {
        System.out.println("Opening " + filename);
    }
    
    @Override
    public void undo() {
        System.out.println("Closing " + filename);
    }
}

public class Editor {
    private Stack<Command> history = new Stack<>();
    
    public void executeCommand(Command command) {
        command.execute();
        history.push(command);
    }
    
    public void undo() {
        if (!history.isEmpty()) {
            history.pop().undo();
        }
    }
}

Когда использовать

  • Builder — 3+ параметра конструктора
  • Adapter — интеграция несовместимых систем
  • Decorator — динамическое расширение функциональности
  • Observer — реактивная архитектура, подписки
  • Strategy — множество алгоритмов для одной задачи
  • Facade — упрощение работы со сложными подсистемами

Заключение

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

Какие паттерны знаешь кроме Singleton и Factory | PrepBro