← Назад к вопросам
Приведи пример использования Open-Closed Principle
2.0 Middle🔥 71 комментариев
#Архитектура и паттерны#ООП
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI28 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Open-Closed Principle (OCP)
OCP — один из SOLID принципов, который гласит: класс должен быть открыт для расширения, но закрыт для модификации. Это значит, что новую функциональность добавляем через наследование/композицию, не меняя исходный код.
Плохой пример (нарушение OCP)
class PaymentProcessor {
processPayment(method: string, amount: number) {
if (method === credit-card) {
// логика обработки карты
console.log(`Processing credit card payment: $${amount}`);
} else if (method === paypal) {
// логика обработки PayPal
console.log(`Processing PayPal payment: $${amount}`);
} else if (method === crypto) {
// логика обработки крипто
console.log(`Processing crypto payment: $${amount}`);
}
}
}
Проблемы:
- При добавлении нового способа оплаты нужно менять класс PaymentProcessor
- Класс нарушает SRP (Single Responsibility) — у него много причин для изменения
- Сложно тестировать каждый способ отдельно
Хороший пример (соблюдение OCP)
// Интерфейс для платёжных систем
interface PaymentMethod {
process(amount: number): Promise<void>;
}
// Реализация для кредитной карты
class CreditCardPayment implements PaymentMethod {
async process(amount: number): Promise<void> {
console.log(`Processing credit card payment: $${amount}`);
// специфичная логика для карты
}
}
// Реализация для PayPal
class PayPalPayment implements PaymentMethod {
async process(amount: number): Promise<void> {
console.log(`Processing PayPal payment: $${amount}`);
// специфичная логика для PayPal
}
}
// Реализация для крипто
class CryptoPayment implements PaymentMethod {
async process(amount: number): Promise<void> {
console.log(`Processing crypto payment: $${amount}`);
// специфичная логика для крипто
}
}
// Обработчик платежей (закрыт для модификации)
class PaymentProcessor {
constructor(private paymentMethod: PaymentMethod) {}
async processPayment(amount: number): Promise<void> {
await this.paymentMethod.process(amount);
}
}
Использование
// Добавляем новый способ оплаты без изменения PaymentProcessor
const creditCardPayment = new CreditCardPayment();
const processor = new PaymentProcessor(creditCardPayment);
await processor.processPayment(100);
// Позже добавляем Apple Pay
class ApplePayPayment implements PaymentMethod {
async process(amount: number): Promise<void> {
console.log(`Processing Apple Pay: $${amount}`);
}
}
const applePayPayment = new ApplePayPayment();
const processor2 = new PaymentProcessor(applePayPayment);
await processor2.processPayment(100);
Преимущества этого подхода
✅ Легко добавлять новые платёжные системы — просто создаём новый класс, реализующий PaymentMethod
✅ PaymentProcessor не меняется — закрыт для модификации
✅ Каждый способ оплаты в отдельном классе — легко тестировать
✅ Соблюдается SRP — каждый класс отвечает за одно
✅ Легко подменять реализации — удобно для dependency injection и мокирования в тестах
Ещё один пример: логирование
interface Logger {
log(message: string): void;
}
class ConsoleLogger implements Logger {
log(message: string): void {
console.log(message);
}
}
class FileLogger implements Logger {
log(message: string): void {
// писать в файл
}
}
class UserService {
constructor(private logger: Logger) {}
createUser(name: string) {
this.logger.log(`User created: ${name}`);
}
}
// Меняем логгер без изменения UserService
const service1 = new UserService(new ConsoleLogger());
const service2 = new UserService(new FileLogger());
Итог
OCP достигается через:
- Интерфейсы/абстракции — определяют контракт
- Наследование/реализацию — расширяем функциональность
- Dependency Injection — подставляем нужные реализации
- Полиморфизм — используем разные реализации прозрачно
Это делает код гибче, понятнее и проще в поддержке.