Какие знаешь паттерны для создания структур данных?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Паттерны создания структур данных в Java
Это фундаментальная тема, которая охватывает различные подходы к инициализации и организации данных. Расскажу о наиболее важных паттернах, используемых в практике.
Builder (Строитель)
Builder — один из самых популярных паттернов для создания сложных объектов с множеством параметров. Он позволяет пошагово конструировать объект и делает код более читаемым.
public class Person {
private String name;
private int age;
private String email;
private String address;
private Person(Builder builder) {
this.name = builder.name;
this.age = builder.age;
this.email = builder.email;
this.address = builder.address;
}
public static class Builder {
private String name;
private int age;
private String email;
private String address;
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 address(String address) {
this.address = address;
return this;
}
public Person build() {
return new Person(this);
}
}
}
// Использование
Person person = new Person.Builder()
.name("John")
.age(30)
.email("john@example.com")
.address("123 Main St")
.build();
Factory Method (Фабричный метод)
Factory Method инкапсулирует логику создания объектов и позволяет скрывать реализацию. Это особенно полезно, когда тип создаваемого объекта определяется во время выполнения.
public abstract class DatabaseConnection {
public abstract void connect();
public static DatabaseConnection create(String dbType) {
switch(dbType.toLowerCase()) {
case "mysql":
return new MySQLConnection();
case "postgresql":
return new PostgreSQLConnection();
default:
throw new IllegalArgumentException("Unknown DB type");
}
}
}
public class MySQLConnection extends DatabaseConnection {
@Override
public void connect() {
System.out.println("Connected to MySQL");
}
}
public class PostgreSQLConnection extends DatabaseConnection {
@Override
public void connect() {
System.out.println("Connected to PostgreSQL");
}
}
// Использование
DatabaseConnection conn = DatabaseConnection.create("mysql");
conn.connect();
Abstract Factory (Абстрактная фабрика)
Этот паттерн используется, когда необходимо создавать семейства взаимосвязанных объектов без указания их конкретных классов.
public interface UIFactory {
Button createButton();
TextField createTextField();
}
public class WindowsUIFactory implements UIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public TextField createTextField() {
return new WindowsTextField();
}
}
public class MacUIFactory implements UIFactory {
@Override
public Button createButton() {
return new MacButton();
}
@Override
public TextField createTextField() {
return new MacTextField();
}
}
Singleton (Одиночка)
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;
}
}
// Или double-checked locking
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized(Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
Prototype (Прототип)
Prototype позволяет создавать новые объекты путём копирования существующего объекта (прототипа), вместо создания с нуля.
public class Shape implements Cloneable {
private String color;
private int size;
@Override
public Shape clone() throws CloneNotSupportedException {
return (Shape) super.clone();
}
}
// Использование
Shape original = new Shape();
original.setColor("red");
original.setSize(10);
Shape copy = original.clone();
Object Pool (Пул объектов)
Используется для переиспользования дорогостоящих объектов вместо их создания и удаления.
public class ConnectionPool {
private Queue<Connection> available;
private Set<Connection> inUse;
private int maxSize;
public ConnectionPool(int maxSize) {
this.maxSize = maxSize;
this.available = new LinkedList<>();
this.inUse = new HashSet<>();
}
public synchronized Connection acquire() throws InterruptedException {
while (available.isEmpty()) {
if (inUse.size() < maxSize) {
Connection conn = new Connection();
available.add(conn);
} else {
wait();
}
}
Connection conn = available.poll();
inUse.add(conn);
return conn;
}
public synchronized void release(Connection conn) {
inUse.remove(conn);
available.add(conn);
notifyAll();
}
}
Когда использовать какой паттерн
- Builder: Объекты с множеством параметров, особенно с опциональными значениями
- Factory Method: Когда тип объекта зависит от параметров
- Abstract Factory: Когда нужны семейства взаимосвязанных объектов
- Singleton: Ресурсы, которые должны быть единственными (конфиг, логгер)
- Prototype: Когда копирование дешевле, чем создание с нуля
- Object Pool: Дорогостоящие ресурсы, которые часто создаются/удаляются
Выбор паттерна зависит от специфики задачи, требований к производительности и удобству использования API.