Принцип единой ответственности в 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()
Похожие посты
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *