Классические паттерны проектирования (Singleton, Factory Method, Abstract Factory, Builder, Strategy, Observer, Command..)
1️⃣ Как кратко ответить
Классические паттерны проектирования — это проверенные временем решения общих проблем проектирования в объектно-ориентированном программировании. Singleton гарантирует наличие только одного экземпляра класса. Factory Method и Abstract Factory предоставляют интерфейсы для создания объектов, позволяя подклассам изменять тип создаваемых объектов. Builder отделяет конструирование сложного объекта от его представления. Strategy определяет семейство алгоритмов, инкапсулирует их и делает взаимозаменяемыми. Observer позволяет объектам подписываться на события другого объекта. Command превращает запросы в объекты, позволяя параметризовать клиентов с помощью различных запросов.
2️⃣ Подробное объяснение темы
Паттерны проектирования — это шаблоны решений для часто встречающихся проблем в разработке программного обеспечения. Они помогают сделать код более гибким, модульным и легким для понимания. Рассмотрим несколько классических паттернов:
Singleton
Singleton гарантирует, что у класса будет только один экземпляр, и предоставляет глобальную точку доступа к этому экземпляру. Это полезно, когда нужно контролировать доступ к какому-то ресурсу, например, к базе данных или файлу конфигурации.
public class Singleton {
private static Singleton instance;
private Singleton() {
// Приватный конструктор предотвращает создание экземпляров извне
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
private static Singleton instance;— статическая переменная для хранения единственного экземпляра.private Singleton()— приватный конструктор, чтобы предотвратить создание экземпляров извне.public static Singleton getInstance()— метод для получения единственного экземпляра, создает его при первом вызове.
Factory Method
Factory Method предоставляет интерфейс для создания объектов, но позволяет подклассам изменять тип создаваемых объектов. Это полезно, когда класс не знает, какие подклассы ему нужно создать.
abstract class Product {
// Абстрактный продукт
}
class ConcreteProduct extends Product {
// Конкретная реализация продукта
}
abstract class Creator {
public abstract Product factoryMethod();
public void someOperation() {
Product product = factoryMethod();
// Использование продукта
}
}
class ConcreteCreator extends Creator {
public Product factoryMethod() {
return new ConcreteProduct();
}
}
abstract class Product— абстрактный класс продукта.class ConcreteProduct— конкретная реализация продукта.abstract class Creator— абстрактный класс создателя с абстрактным методомfactoryMethod.class ConcreteCreator— конкретный создатель, реализующий методfactoryMethod.
Abstract Factory
Abstract Factory предоставляет интерфейс для создания семейств связанных или зависимых объектов без указания их конкретных классов. Это полезно для создания объектов, которые должны работать вместе.
interface AbstractFactory {
ProductA createProductA();
ProductB createProductB();
}
class ConcreteFactory1 implements AbstractFactory {
public ProductA createProductA() {
return new ProductA1();
}
public ProductB createProductB() {
return new ProductB1();
}
}
interface ProductA {
// Интерфейс продукта A
}
interface ProductB {
// Интерфейс продукта B
}
class ProductA1 implements ProductA {
// Конкретная реализация продукта A1
}
class ProductB1 implements ProductB {
// Конкретная реализация продукта B1
}
interface AbstractFactory— интерфейс фабрики для создания продуктов.class ConcreteFactory1— конкретная фабрика, создающая конкретные продукты.interface ProductAиinterface ProductB— интерфейсы продуктов.class ProductA1иclass ProductB1— конкретные реализации продуктов.
Builder
Builder отделяет конструирование сложного объекта от его представления, позволяя создавать разные представления с помощью одного и того же процесса конструирования.
class Product {
private String partA;
private String partB;
public void setPartA(String partA) {
this.partA = partA;
}
public void setPartB(String partB) {
this.partB = partB;
}
}
abstract class Builder {
protected Product product = new Product();
public abstract void buildPartA();
public abstract void buildPartB();
public Product getResult() {
return product;
}
}
class ConcreteBuilder extends Builder {
public void buildPartA() {
product.setPartA("Part A");
}
public void buildPartB() {
product.setPartB("Part B");
}
}
class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public void construct() {
builder.buildPartA();
builder.buildPartB();
}
}
class Product— класс продукта с частямиpartAиpartB.abstract class Builder— абстрактный строитель с методами для создания частей продукта.class ConcreteBuilder— конкретный строитель, реализующий методы создания частей.class Director— класс, управляющий процессом создания продукта.
Strategy
Strategy определяет семейство алгоритмов, инкапсулирует их и делает взаимозаменяемыми. Это позволяет изменять алгоритмы независимо от клиентов, которые их используют.
interface Strategy {
void execute();
}
class ConcreteStrategyA implements Strategy {
public void execute() {
System.out.println("Executing strategy A");
}
}
class ConcreteStrategyB implements Strategy {
public void execute() {
System.out.println("Executing strategy B");
}
}
class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void executeStrategy() {
strategy.execute();
}
}
interface Strategy— интерфейс стратегии с методомexecute.class ConcreteStrategyAиclass ConcreteStrategyB— конкретные реализации стратегий.class Context— класс, использующий стратегию.
Observer
Observer позволяет объектам подписываться на события другого объекта и получать уведомления об изменениях состояния.
interface Observer {
void update(String message);
}
class ConcreteObserver implements Observer {
public void update(String message) {
System.out.println("Received message: " + message);
}
}
class Subject {
private List<Observer> observers = new ArrayList<>();
public void addObserver(Observer observer) {
observers.add(observer);
}
public void removeObserver(Observer observer) {
observers.remove(observer);
}
public void notifyObservers(String message) {
for (Observer observer : observers) {
observer.update(message);
}
}
}
interface Observer— интерфейс наблюдателя с методомupdate.class ConcreteObserver— конкретный наблюдатель, реализующий методupdate.class Subject— класс, управляющий списком наблюдателей и уведомляющий их об изменениях.
Command
Command превращает запросы в объекты, позволяя параметризовать клиентов с помощью различных запросов, ставить запросы в очередь или протоколировать их.
interface Command {
void execute();
}
class ConcreteCommand implements Command {
private Receiver receiver;
public ConcreteCommand(Receiver receiver) {
this.receiver = receiver;
}
public void execute() {
receiver.action();
}
}
class Receiver {
public void action() {
System.out.println("Action performed by receiver");
}
}
class Invoker {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void executeCommand() {
command.execute();
}
}
interface Command— интерфейс команды с методомexecute.class ConcreteCommand— конкретная команда, вызывающая действие у получателя.class Receiver— класс, выполняющий действие.class Invoker— класс, вызывающий команду.
Эти паттерны помогают разработчикам создавать более гибкие и поддерживаемые системы, обеспечивая четкое разделение обязанностей и улучшая повторное использование кода.
🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!
Подписаться