digital-garden/dev/architecture/Open Closed Principle.md
Struchkov Mark 2c945630a3
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone Build is passing
Обновление и рефакторинг
2024-11-23 21:34:40 +03:00

5.4 KiB
Raw Blame History

aliases tags date
Open/Closed Principle
OCP
Принцип открытости/закрытости
maturity/🌱
2024-09-27

Классы и модули должны быть открыты для расширения, но закрыты для модификации. Это означает, что функциональность можно добавлять без изменения существующего кода. Такой подход позволяет минимизировать риск возникновения ошибок в уже работающей системе при внедрении новых функций. Принцип открытости/закрытости (Open-Closed Principle, OCP) является вторым из пяти SOLID-принципов и способствует созданию гибкой и поддерживаемой архитектуры.

Обычно для реализации принципа используются:

  • Интерфейсы или абстрактные классы, которые задают общую структуру поведения.
  • Полиморфизм, позволяющий создавать новые реализации без изменения базового кода.

Следование OCP снижает связанность модулей, делает код проще в тестировании и облегчает внедрение новых функций.

Преимущества соблюдения OCP:

  1. Гибкость кода: Добавление нового функционала не требует изменений существующего кода, что снижает риск ошибок.
  2. Улучшенная тестируемость: Изолированные реализации проще тестировать независимо друг от друга.
  3. Снижение связанности: Код становится более модульным, и изменения в одной части системы не затрагивают другие.
  4. Поддерживаемость: Разработчики могут легко добавлять новые возможности без угрозы сломать существующий функционал.

Пример нарушения OCP

Рассмотрим класс, который обрабатывает оплату, поддерживая только один способ оплаты через кредитную карту:

public class PaymentProcessor {
    public void processPayment(String type, double amount) {
        if (type.equals("credit_card")) {
            // Логика оплаты через кредитную карту
        }
    }
}

Если требуется добавить поддержку нового способа оплаты, например, PayPal, придется модифицировать метод processPayment:

public class PaymentProcessor {
    public void processPayment(String type, double amount) {
        if (type.equals("credit_card")) {
            // Логика оплаты через кредитную карту
        } else if (type.equals("paypal")) {
            // Логика оплаты через PayPal
        }
    }
}

Такой подход нарушает OCP, так как для добавления нового функционала приходится изменять уже существующий код. Это увеличивает риск ошибок и затрудняет сопровождение.

Используем интерфейсы для реализации разных способов оплаты:

public interface PaymentMethod {
    void pay(double amount);
}

public class CreditCardPayment implements PaymentMethod {
    @Override
    public void pay(double amount) {
        // Оплата через кредитную карту
    }
}

public class PayPalPayment implements PaymentMethod {
    @Override
    public void pay(double amount) {
        // Оплата через PayPal
    }
}

Теперь процессор оплаты будет работать с интерфейсом PaymentMethod, не завися от конкретных реализаций:

public class PaymentProcessor {
    private PaymentMethod paymentMethod;

    public PaymentProcessor(PaymentMethod paymentMethod) {
        this.paymentMethod = paymentMethod;
    }

    public void processPayment(double amount) {
        paymentMethod.pay(amount);
    }
}

Для добавления нового способа оплаты достаточно создать новую реализацию PaymentMethod, не изменяя код процессора.


Мета информация

Область:: ../../meta/zero/00 Архитектура ПО Родитель:: SOLID Источник:: Создана:: 2024-09-27 Автор::

Дополнительные материалы

Дочерние заметки