Какие паттерны проектирования GoF вы использовали на практике?

Ответ

Да, использовал паттерны из каталога Gang of Four (GoF). Они помогают решать типовые задачи проектирования, делая код более гибким, переиспользуемым и поддерживаемым.

Наиболее часто применяемые паттерны:

  • Singleton (Одиночка): Для создания единственного экземпляра класса (например, подключения к базе данных, логгера).
  • Factory (Фабрика): Для инкапсуляции логики создания объектов, не привязывая клиентский код к конкретным классам.
  • Builder (Строитель): Для пошагового создания сложных объектов, отделяя конструирование от представления.
  • Observer (Наблюдатель): Для реализации механизма подписки и уведомлений об изменениях состояния.
  • Strategy (Стратегия): Для определения семейства алгоритмов, инкапсуляции каждого из них и обеспечения их взаимозаменяемости.

Пример Singleton на Java:

public class Database {
    private static volatile Database instance;

    private Database() {
        // Инициализация подключения
    }

    public static Database getInstance() {
        if (instance == null) {
            synchronized (Database.class) {
                if (instance == null) {
                    instance = new Database();
                }
            }
        }
        return instance;
    }
}

Пример Factory на Java:

public interface Shape {
    void draw();
}

public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a circle");
    }
}

public class ShapeFactory {
    public Shape createShape(String type) {
        if (type.equalsIgnoreCase("CIRCLE")) {
            return new Circle();
        }
        // ... другие типы
        throw new IllegalArgumentException("Unknown shape type: " + type);
    }
}
// Использование
Shape shape = new ShapeFactory().createShape("CIRCLE");
shape.draw();

Ответ 18+ 🔞

А, паттерны эти, из банды четырёх! Ну да, блядь, использовал, куда ж без них. Это ж как гайки в механизме — без них всё развалится нахуй, а с ними хоть какую-то структуру держать можно, чтобы не превращать проект в свалку говнокода.

Вот что чаще всего в ход идёт, на моей практике:

  • Одиночка (Singleton): Когда нужно, чтобы какая-то хуйня была в единственном экземпляре на всю систему. Ну, типа подключения к базе или логгера, который орет на весь проект. Чтобы не плодить сущностей, как говно за баней.
  • Фабрика (Factory): Чтоб клиентский код не парился, какой именно объект создавать. Сказал «дай мне круг» — получил круг. А там внутри хоть квадрат с рогами, если логика изменится — ему похуй.
  • Строитель (Builder): Когда объект собирается из кучи параметров, и если тыкать их все в конструктор — это пиздец, а не сигнатура. Лучше по кирпичику сложить, красиво.
  • Наблюдатель (Observer): Чтобы одна часть системы могла крикнуть «эй, пацаны, я изменилась!», а другие, кто подписался, могли это услышать и сделать свои дела. Без прямых связей, а то опять всё спутается.
  • Стратегия (Strategy): Когда есть несколько алгоритмов делать одно и то же (сортировать, считать, хуй знает что), и нужно иметь возможность их менять на лету, не перелопачивая половину кода.

Вот, смотри, как Одиночку на Java делают, чтоб не накосячить с многопоточностью:

public class Database {
    private static volatile Database instance;

    private Database() {
        // Тут инициализация, подключение и прочая муть
    }

    public static Database getInstance() {
        if (instance == null) {
            synchronized (Database.class) {
                if (instance == null) {
                    instance = new Database();
                }
            }
        }
        return instance;
    }
}

А вот Фабрика, простенькая, для примера:

public interface Shape {
    void draw();
}

public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Рисую круг, блядь");
    }
}

public class ShapeFactory {
    public Shape createShape(String type) {
        if (type.equalsIgnoreCase("CIRCLE")) {
            return new Circle();
        }
        // ... другие фигуры
        throw new IllegalArgumentException("Чё за тип такой, а? Не знаю: " + type);
    }
}
// Использование
Shape shape = new ShapeFactory().createShape("CIRCLE");
shape.draw();

Вот так вот, ёпта. Не серебряная пуля, конечно, но когда применяешь к месту — жить становится проще, а код не хочется сразу в помойку выкидывать. Главное — не пытаться впихнуть паттерн куда ни попадя, а то получится архитектурный маразм, в рот меня чих-пых.