← Назад к вопросам
Приведи пример нарушения принципа Open-Close
2.3 Middle🔥 231 комментариев
#SOLID и паттерны проектирования
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Нарушение принципа Open/Closed Principle (OCP)
Принцип Open/Closed гласит: класс должен быть открыт для расширения, но закрыт для модификации. Нарушение этого принципа означает, что при добавлении нового функционала приходится менять уже существующий код.
Пример нарушения OCP
Рассмотрим систему расчёта скидок для различных типов клиентов:
public class DiscountCalculator {
public double calculateDiscount(Customer customer) {
if (customer.getType().equals("REGULAR")) {
return customer.getTotalPurchases() * 0.05; // 5% скидка
} else if (customer.getType().equals("PREMIUM")) {
return customer.getTotalPurchases() * 0.10; // 10% скидка
} else if (customer.getType().equals("VIP")) {
return customer.getTotalPurchases() * 0.20; // 20% скидка
}
return 0;
}
}
Проблемы:
- При добавлении нового типа клиента (например, CORPORATE) нужно менять метод
calculateDiscount - Класс нарушает принцип единственной ответственности (SRP)
- Код становится всё более запутанным с новыми условиями
- Сложно тестировать
Правильное решение (следование OCP)
public interface DiscountStrategy {
double calculate(Customer customer);
}
public class RegularCustomerDiscount implements DiscountStrategy {
@Override
public double calculate(Customer customer) {
return customer.getTotalPurchases() * 0.05;
}
}
public class PremiumCustomerDiscount implements DiscountStrategy {
@Override
public double calculate(Customer customer) {
return customer.getTotalPurchases() * 0.10;
}
}
public class VIPCustomerDiscount implements DiscountStrategy {
@Override
public double calculate(Customer customer) {
return customer.getTotalPurchases() * 0.20;
}
}
public class DiscountCalculator {
private Map<String, DiscountStrategy> strategies = new HashMap<>();
public DiscountCalculator() {
strategies.put("REGULAR", new RegularCustomerDiscount());
strategies.put("PREMIUM", new PremiumCustomerDiscount());
strategies.put("VIP", new VIPCustomerDiscount());
}
public double calculateDiscount(Customer customer) {
DiscountStrategy strategy = strategies.get(customer.getType());
return strategy != null ? strategy.calculate(customer) : 0;
}
}
Преимущества:
- Класс
DiscountCalculatorзакрыт для модификации - Система открыта для расширения: добавляем новый тип скидки без изменения существующего кода
- Каждая стратегия отвечает за одно: расчёт скидки для конкретного типа клиента
- Легче тестировать каждую реализацию отдельно
- Соответствует паттерну Strategy
Теперь при добавлении нового типа клиента (CORPORATE) нужно просто создать новый класс CorporateCustomerDiscount и зарегистрировать его в Map — без изменения основного кода.