Умение писать классы ещё не значит умение строить хорошие программы. Эта тема — мост от ООП к дизайну: мы решаем, что должен делать класс и насколько он должен зависеть от других.
Четыре принципа вкратце
- Инкапсуляция: состояние скрыто и меняется методами (свойства).
- Наследование: подкласс берёт поведение родителя (наследование и
super). - Полиморфизм: один вызов по-разному работает на разных объектах (классы и объекты).
- Абстракция: показываем, что делает объект, а не как (ABC).
from abc import ABC, abstractmethod
class Shape(ABC): # abstraction: what, not how
@abstractmethod
def area(self): ...
class Square(Shape): # inheritance
def __init__(self, side):
self._side = side # encapsulation: hidden state
def area(self):
return self._side ** 2
class Circle(Shape):
def __init__(self, r):
self._r = r
def area(self):
return round(3.14159 * self._r ** 2, 2)
for shape in (Square(3), Circle(1)): # polymorphism: one call, many behaviours
print(type(shape).__name__, shape.area())Square 9
Circle 3.14Эти принципы — инструменты. Дизайн — это выбор, когда и как их применять. Три главных вопроса: для чего этот класс? от кого он зависит? что сломается, если его изменить?
Цель дизайна
Программу пишут один раз, а меняют многократно. Хороший дизайн делает изменение дешёвым. Это показывают две меры: связность (cohesion) — насколько части класса относятся друг к другу (цель: высокая) и зацепление (coupling) — зависимость классов друг от друга (цель: низкое).