Принцип единой ответственности в Python — применение на примерах
В этом уроке вы узнаете о первом из пяти принципов SOLID — принципе единой ответственности и о том, как его применять и реализовать в Python.
Что такое SOLID
SOLID — это аббревиатура, обозначающая пять принципов проектирования программного обеспечения, составленных дядей Бобом:
- S – Single responsibility Principle (принцип единой ответственности)
- O – Open-closed Principle (принцип открытости-закрытости)
- L – Liskov Substitution Principle (принцип подстановки Лисков)
- I – Interface Segregation Principle (разделение интерфейса)
- D – Dependency Inversion Principle (инверсия зависимостей)
Единая ответственность – это первый принцип из 5 принципов SOLID.
Введение в принцип единой ответственности
Принцип единой ответственности (SRP) гласит, что у каждого класса, метода и функции должна быть только одна задача или одна причина для изменения.
Целями принципа единой ответственности являются:
- Создавайте высокосвязные и надежные классы, методы и функции.
- Продвигайте состав класса.
- Избегайте дублирования кода.
Давайте посмотрим на следующий класс Person:
class Person: def __init__(self, name): self.name = name def __repr__(self): return f'Person(name={self.name})' @classmethod def save(cls, person): print(f'Save the {person} to the database') if __name__ == '__main__': p = Person('John Doe') Person.save(p)
Этот класс Person выполняет две задачи:
- Управление имуществом человека.
- Сохранение человека в базе данных.
Позже, если вы захотите сохранить Person в другом хранилище, например в файле, вам нужно будет изменить метод save(), который также изменит весь класс Person.
Чтобы класс Person соответствовал принципу единой ответственности, вам необходимо создать еще один класс, отвечающий за хранение Person в базе данных. Например:
class Person: def __init__(self, name): self.name = name def __repr__(self): return f'Person(name={self.name})' class PersonDB: def save(self, person): print(f'Save the {person} to the database') if __name__ == '__main__': p = Person('John Doe') db = PersonDB() db.save(p)
В этом проекте мы разделяем класс Person на два класса: Person и PersonDB:
- Класс Person отвечает за управление свойствами человека.
- Класс PersonDB отвечает за хранение человека в базе данных.
В этом проекте, если вы хотите сохранить Person в другом хранилище, вы можете определить для этого другой класс. И вам не нужно менять класс Person. При разработке классов следует объединять связанные методы, имеющие одну и ту же причину изменения. Другими словами, вам следует разделить классы, если они изменяются по разным причинам.
В этом проекте есть одна проблема, которую вам нужно решить с двумя классами: Person и PersonDB.
Чтобы сделать это более удобным, вы можете использовать шаблон фасада, чтобы класс Person был фасадом для класса PersonDB, например:
class PersonDB: def save(self, person): print(f'Save the {person} to the database') class Person: def __init__(self, name): self.name = name self.db = PersonDB() def __repr__(self): return f'Person(name={self.name})' def save(self): self.db.save(person=self) if __name__ == '__main__': p = Person('John Doe') p.save()