Принцип открытости/закрытости (Open/Closed Principle, OCP) – это один из пяти принципов SOLID, который утверждает, что программные сущности (классы, модули, функции) должны быть открытыми для расширения, но закрытыми для модификации. Этот принцип поощряет создание гибкого и расширяемого кода, позволяя добавлять новую функциональность без изменения существующего кода.
Ключевые концепции OCP:
- Открытость для расширения (Open for Extension): Это означает, что код и его компоненты должны быть спроектированы таким образом, чтобы новую функциональность можно было добавить путем создания новых классов или модулей, а не путем изменения существующего кода.
- Закрытость для модификации (Closed for Modification): Это означает, что существующий код и его компоненты не должны изменяться, когда добавляется новая функциональность. Вместо этого новый функциональный код должен расширять существующий без его модификации.
Пример с нарушением OCP:
python
class Shape: def area(self): pass class Circle(Shape): def __init__(self, radius): self.radius = radius def area(self): return 3.14159265359 * self.radius ** 2 class Square(Shape): def __init__(self, side): self.side = side def area(self): return self.side ** 2 class AreaCalculator: def calculate_area(self, shapes): total_area = 0 for shape in shapes: if isinstance(shape, Circle): total_area += 3.14159265359 * shape.radius ** 2 elif isinstance(shape, Square): total_area += shape.side ** 2 return total_area
В этом примере, чтобы добавить новую форму, например, треугольник, потребовалось бы изменить класс AreaCalculator
, что нарушает принцип OCP. Если мы придерживаемся OCP, мы должны проектировать систему так, чтобы можно было добавить новую форму, не изменяя AreaCalculator
.
Пример, соблюдающий OCP:
python
class Shape: def area(self): pass class Circle(Shape): def __init__(self, radius): self.radius = radius def area(self): return 3.14159265359 * self.radius ** 2 class Square(Shape): def __init__(self, side): self.side = side def area(self): return self.side ** 2 class AreaCalculator: def calculate_area(self, shapes): total_area = 0 for shape in shapes: total_area += shape.area() return total_area
В этом примере AreaCalculator
остается закрытым для модификации, и мы можем добавлять новые формы, создавая только новые классы, не изменяя существующий код. Это соблюдение принципа OCP.