Какие знаешь реализации паттернов?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Реализации паттернов в Java
Дизайн паттерны — это проверенные решения для типичных проблем проектирования. Я хорошо знаком с основными паттернами и их реализациями на Java.
Паттерны Порождения (Creational)
Эти паттерны управляют процессом создания объектов.
1. Singleton (Одиночка)
Гарантирует, что класс имеет только один экземпляр и предоставляет глобальный доступ.
public class Singleton {
private static Singleton instance;
private Singleton() {} // Приватный конструктор
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
// Лучше — eager initialization
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
// Еще лучше — enum (потокобезопасный и защищен от сериализации)
public enum Singleton {
INSTANCE;
public void doSomething() {
// ...
}
}
Применение: Логирование, конфигурация, пулы соединений.
2. Factory (Фабрика)
Создает объекты без указания конкретных классов.
// Интерфейс
interface Transport {
void deliver();
}
// Конкретные реализации
class Truck implements Transport {
@Override
public void deliver() {
System.out.println("Delivering by truck");
}
}
class Ship implements Transport {
@Override
public void deliver() {
System.out.println("Delivering by ship");
}
}
// Фабрика
public class TransportFactory {
public static Transport createTransport(String type) {
if ("truck".equals(type)) {
return new Truck();
} else if ("ship".equals(type)) {
return new Ship();
}
throw new IllegalArgumentException("Unknown transport type");
}
}
// Использование
Transport transport = TransportFactory.createTransport("truck");
transport.deliver();
3. Builder (Строитель)
Создает сложные объекты пошагово.
public class Car {
private String brand;
private String model;
private String color;
private int year;
private Car(Builder builder) {
this.brand = builder.brand;
this.model = builder.model;
this.color = builder.color;
this.year = builder.year;
}
public static class Builder {
private String brand;
private String model;
private String color = "Black"; // default
private int year;
public Builder brand(String brand) {
this.brand = brand;
return this;
}
public Builder model(String model) {
this.model = model;
return this;
}
public Builder color(String color) {
this.color = color;
return this;
}
public Builder year(int year) {
this.year = year;
return this;
}
public Car build() {
return new Car(this);
}
}
}
// Использование
Car car = new Car.Builder()
.brand("Toyota")
.model("Camry")
.color("Red")
.year(2023)
.build();
Паттерны Структуры (Structural)
Эти паттерны управляют связями между объектами.
4. Adapter (Адаптер)
Преобразует интерфейс класса в другой интерфейс, ожидаемый клиентами.
// Старый интерфейс
interface OldPaymentSystem {
void pay(double amount);
}
class OldPaymentImpl implements OldPaymentSystem {
@Override
public void pay(double amount) {
System.out.println("Old payment: " + amount);
}
}
// Новый интерфейс
interface PaymentProcessor {
void processPayment(double amount);
}
// Адаптер
class PaymentAdapter implements PaymentProcessor {
private OldPaymentSystem oldSystem;
public PaymentAdapter(OldPaymentSystem oldSystem) {
this.oldSystem = oldSystem;
}
@Override
public void processPayment(double amount) {
oldSystem.pay(amount);
}
}
5. Decorator (Декоратор)
Добавляет новую функциональность к объекту без изменения его структуры.
interface Component {
void operation();
}
class ConcreteComponent implements Component {
@Override
public void operation() {
System.out.println("Basic operation");
}
}
abstract class Decorator implements Component {
protected Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public void operation() {
component.operation();
}
}
class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}
@Override
public void operation() {
super.operation();
System.out.println("Added functionality");
}
}
// Использование
Component component = new ConcreteComponent();
Component decorated = new ConcreteDecorator(component);
decorated.operation();
// Вывод:
// Basic operation
// Added functionality
6. Proxy (Прокси)
Предоставляет заместителя или placeholder для другого объекта.
interface Image {
void display();
}
class RealImage implements Image {
private String filename;
public RealImage(String filename) {
this.filename = filename;
loadImage();
}
private void loadImage() {
System.out.println("Loading image: " + filename);
}
@Override
public void display() {
System.out.println("Displaying: " + filename);
}
}
class ImageProxy implements Image {
private String filename;
private RealImage realImage;
public ImageProxy(String filename) {
this.filename = filename;
}
@Override
public void display() {
if (realImage == null) {
realImage = new RealImage(filename); // Lazy loading
}
realImage.display();
}
}
Паттерны Поведения (Behavioral)
Эти паттерны определяют взаимодействие между объектами и распределение ответственности.
7. Observer (Наблюдатель)
Определяет отношение один-ко-многим между объектами.
interface Observer {
void update(String message);
}
class Subject {
private List<Observer> observers = new ArrayList<>();
public void subscribe(Observer observer) {
observers.add(observer);
}
public void unsubscribe(Observer observer) {
observers.remove(observer);
}
public void notify(String message) {
for (Observer observer : observers) {
observer.update(message);
}
}
}
class ConcreteObserver implements Observer {
@Override
public void update(String message) {
System.out.println("Received: " + message);
}
}
// Использование
Subject subject = new Subject();
subject.subscribe(new ConcreteObserver());
subject.subscribe(new ConcreteObserver());
subject.notify("Event happened!");
8. Strategy (Стратегия)
Определяет семейство алгоритмов, инкапсулирует каждый и делает их взаимозаменяемыми.
interface PaymentStrategy {
void pay(double amount);
}
class CreditCardPayment implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("Paying " + amount + " by credit card");
}
}
class PayPalPayment implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("Paying " + amount + " by PayPal");
}
}
class ShoppingCart {
private PaymentStrategy strategy;
public ShoppingCart(PaymentStrategy strategy) {
this.strategy = strategy;
}
public void checkout(double amount) {
strategy.pay(amount);
}
}
// Использование
ShoppingCart cart = new ShoppingCart(new CreditCardPayment());
cart.checkout(100);
cart = new ShoppingCart(new PayPalPayment());
cart.checkout(200);
9. Template Method (Шаблонный метод)
Определяет скелет алгоритма в базовом классе.
abstract class DataProcessor {
// Шаблонный метод
public void process() {
readData();
parseData();
saveData();
}
protected abstract void readData();
protected abstract void parseData();
protected abstract void saveData();
}
class CSVProcessor extends DataProcessor {
@Override
protected void readData() {
System.out.println("Reading CSV file");
}
@Override
protected void parseData() {
System.out.println("Parsing CSV");
}
@Override
protected void saveData() {
System.out.println("Saving CSV data");
}
}
10. State (Состояние)
Позволяет объекту изменять своё поведение в зависимости от своего состояния.
interface State {
void handle(Context context);
}
class StartState implements State {
@Override
public void handle(Context context) {
System.out.println("Starting...");
context.setState(new RunningState());
}
}
class RunningState implements State {
@Override
public void handle(Context context) {
System.out.println("Running...");
context.setState(new StoppedState());
}
}
class Context {
private State state;
public Context(State state) {
this.state = state;
}
public void setState(State state) {
this.state = state;
}
public void request() {
state.handle(this);
}
}
Практическое применение
- Spring Framework использует Factory, Singleton, Proxy
- Java Collections используют Iterator, Strategy, Template Method
- JDBC использует Factory, Adapter
- Logging frameworks используют Observer, Factory
Заключение
Знание паттернов позволяет писать более гибкий и поддерживаемый код. Однако важно не переусложнять — используй паттерн только когда в нём есть необходимость.