Четыре кита ООП + практика
Inheritance, Polymorphism, Abstraction, Encapsulation
class Animal:
def speak(self):
pass
class Dog(Animal):
def speak(self):
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"
🔹 Общее поведение — в базовом классе
def make_animal_speak(animal: Animal):
print(animal.speak())
make_animal_speak(Dog()) # Woof!
make_animal_speak(Cat()) # Meow!
🔹 Один интерфейс — разное поведение
from abc import ABC, abstractmethod
class Model(ABC):
@abstractmethod
def train(self): pass
@abstractmethod
def predict(self): pass
# Не можешь создать экземпляр без реализации
class NeuralNet(Model):
def train(self): ...
def predict(self): ...
class BankAccount:
def __init__(self):
self._balance = 0 # защищённое
def deposit(self, amount):
if amount > 0:
self._balance += amount
def get_balance(self):
return self._balance # контролируем доступ
🔹 Скрытие деталей реализации
# Абстрактный — не создаётся
class Service(ABC):
@abstractmethod
def run(self): pass
# Конкретный — можно создать
class TrainingService(Service):
def run(self):
print("Training started")
class Storable(ABC):
@abstractmethod
def save(self): pass
class JSONStorable(Storable):
def save(self):
write_json(self.data)
class DBStorable(Storable):
def save(self):
db.save(self.record)
🔹 Клиент зависит от интерфейса, а не от реализации
class User:
def __init__(self, name):
self.name = name # public
self._temp_token = "" # protected (по соглашению)
self.__secret = "..." # private (name mangling)
🔹 `public`, `_protected`, `__private`
Код как отражение предметной области
class User:
def __init__(self, name, email):
self.name = name
self.email = email
class Order:
def __init__(self, user: User, amount):
self.user = user
self.amount = amount
🔹 Модели соответствуют реальным сущностям
presentation/
├── api.py
application/
├── usecases.py
domain/
├── models.py
└── services.py
infrastructure/
├── database.py
└── email_client.py
🔹 Границы ответственности
class User:
def __init__(self):
self.name = ""
self.email = ""
# А вся логика — где-то в другом месте
def validate_user(user):
return '@' in user.email
❌ Модель без поведения — плохая инкапсуляция
class User:
def __init__(self, name, email):
self.name = name
self.email = email
def is_valid(self):
return '@' in self.email
def upgrade_to_premium(self):
self.role = "premium"
self.send_welcome_email()
✔️ Логика рядом с данными