Назад к вопросам
Middle
69
questionbank

Приведи примеры структурных шаблонов проектирования.

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

  • Адаптер (Adapter): Преобразует интерфейс класса в другой интерфейс, который ждут клиенты. Позволяет классам работать совместно, несмотря на несовместимые интерфейсы.

Пример:

// Целевой интерфейс
interface Target {
    void request();
}

// Адаптируемый класс
class Adaptee {
    public void specificRequest() {
        System.out.println("Specific request");
    }
}

// Адаптер, реализующий целевой интерфейс и содержащий адаптируемый объект
class Adapter implements Target {
    private Adaptee adaptee;

    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void request() {
        adaptee.specificRequest(); // Вызов специфического запроса адаптируемого класса
    }
}
  • Мост (Bridge): Разделяет абстракцию и реализацию так, что они могут изменяться независимо. Позволяет избежать жесткой привязки абстракции к конкретной реализации.

Пример:

// Интерфейс реализации
interface Implementor {
    void operationImpl();
}

// Конкретная реализация A
class ConcreteImplementorA implements Implementor {
    @Override
    public void operationImpl() {
        System.out.println("Concrete Implementor A operation");
    }
}

// Абстракция, содержащая ссылку на реализацию
abstract class Abstraction {
    protected Implementor implementor;

    public Abstraction(Implementor implementor) {
        this.implementor = implementor;
    }

    public abstract void operation();
}

// Расширенная абстракция, использующая реализацию
class RefinedAbstraction extends Abstraction {
    public RefinedAbstraction(Implementor implementor) {
        super(implementor);
    }

    @Override
    public void operation() {
        System.out.println("Refined Abstraction operation");
        implementor.operationImpl(); // Делегирование вызова реализации
    }
}
  • Компоновщик (Composite): Позволяет группировать объекты в древовидные структуры и работать с ними как с отдельными объектами. Обеспечивает единообразный доступ к отдельным объектам и их композициям.

Пример:

import java.util.ArrayList;
import java.util.List;

// Компонент - общий интерфейс для листьев и композиций
interface Component {
    void operation();
}

// Лист - конечный объект в структуре
class Leaf implements Component {
    private String name;

    public Leaf(String name) {
        this.name = name;
    }

    @Override
    public void operation() {
        System.out.println("Leaf " + name + " operation");
    }
}

// Композиция - содержит компоненты
class Composite implements Component {
    private String name;
    private List<Component> children = new ArrayList<>();

    public Composite(String name) {
        this.name = name;
    }

    public void add(Component component) {
        children.add(component);
    }

    public void remove(Component component) {
        children.remove(component);
    }

    @Override
    public void operation() {
        System.out.println("Composite " + name + " operation:");
        for (Component child : children) {
            child.operation(); // Рекурсивный вызов операции для дочерних элементов
        }
    }
}
  • Декоратор (Decorator): Динамически добавляет объектам новые обязанности. Является гибкой альтернативой наследованию для расширения функциональности.

Пример:

// Компонент - базовый интерфейс
interface Component {
    void operation();
}

// Конкретный компонент
class ConcreteComponent implements Component {
    @Override
    public void operation() {
        System.out.println("Concrete Component operation");
    }
}

// Базовый декоратор
abstract class Decorator implements Component {
    protected Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    @Override
    public void operation() {
        component.operation(); // Вызов операции базового компонента
    }
}

// Конкретный декоратор, добавляющий новую функциональность
class ConcreteDecoratorA extends Decorator {
    public ConcreteDecoratorA(Component component) {
        super(component);
    }

    @Override
    public void operation() {
        super.operation();
        addedBehavior(); // Добавление нового поведения
    }

    private void addedBehavior() {
        System.out.println("Added behavior from Decorator A");
    }
}
  • Фасад (Facade): Предоставляет унифицированный интерфейс к группе подсистем. Определяет более простой интерфейс к сложной подсистеме.

Пример:

// Часть подсистемы 1
class SubsystemA {
    public void operationA() {
        System.out.println("Subsystem A operation");
    }
}

// Часть подсистемы 2
class SubsystemB {
    public void operationB() {
        System.out.println("Subsystem B operation");
    }
}

// Фасад, предоставляющий простой интерфейс
class Facade {
    private SubsystemA subsystemA;
    private SubsystemB subsystemB;

    public Facade() {
        subsystemA = new SubsystemA();
        subsystemB = new SubsystemB();
    }

    public void operation() {
        System.out.println("Facade operation:");
        subsystemA.operationA();
        subsystemB.operationB();
    }
}
  • Приспособленец (Flyweight): Используется для эффективной поддержки большого количества мелких объектов. Делит общее состояние между объектами для экономии памяти.

Пример:

import java.util.HashMap;
import java.util.Map;

// Интерфейс приспособленца
interface Flyweight {
    void operation(String extrinsicState);
}

// Конкретный приспособленец (совместное состояние)
class ConcreteFlyweight implements Flyweight {
    private String intrinsicState; // Внутреннее состояние (совместное)

    public ConcreteFlyweight(String intrinsicState) {
        this.intrinsicState = intrinsicState;
    }

    @Override
    public void operation(String extrinsicState) { // Внешнее состояние (уникальное)
        System.out.println("Concrete Flyweight with intrinsic state: " + intrinsicState +
                           ", extrinsic state: " + extrinsicState);
    }
}

// Фабрика приспособленцев
class FlyweightFactory {
    private Map<String, Flyweight> flyweights = new HashMap<>();

    public Flyweight getFlyweight(String key) {
        if (!flyweights.containsKey(key)) {
            flyweights.put(key, new ConcreteFlyweight(key));
        }
        return flyweights.get(key);
    }
}
  • Заместитель (Proxy): Предоставляет суррогат или заместитель для другого объекта для управления доступом к нему. Может выполнять различные задачи, такие как ленивая инициализация, контроль доступа, журналирование.

Пример:

// Интерфейс субъекта
interface Subject {
    void request();
}

// Реальный субъект (реальный объект)
class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("Real Subject handling request");
    }
}

// Заместитель (Proxy)
class Proxy implements Subject {
    private RealSubject realSubject;

    @Override
    public void request() {
        if (realSubject == null) {
            realSubject = new RealSubject(); // Ленивая инициализация
        }
        System.out.println("Proxy handling request before Real Subject");
        realSubject.request();
        System.out.println("Proxy handling request after Real Subject");
    }
}