Паттерн репозиторий - NurOrNuLL/ESDP-AP-5-6-TEAM-2 GitHub Wiki
Паттерн репозиторий
Паттерн «Репозиторий» — это абстракция поверх системы постоянного хранения. Он скрывает скучные детали доступа к данным, делая вид, что все данные находятся прямо в памяти.
Хранилище в абстрактном виде
Простейший репозиторий имеет всего два метода: add() , чтобы поместить новый элемент в репозиторий, и get() , чтобы вернуть ранее добавленный элемент 1 . Мы твердо придерживаемся использования этих методов для доступа к данным в модели и в слое служб предметной области. Это условие не позволяет нам прицепить модель предметной области к базе данных. Вот как будет выглядеть абстрактный базовый класс (ABC) для репозитория:
Самый простой из возможных репозиториев (repository.py)
class AbstractRepository(abc.ABC):
@abc.abstractmethod
def add(self, batch: model.Batch):
raise NotImplementedError
@abc.abstractmethod
def get(self, reference) -> model.Batch:
raise NotImplementedError
АБСТРАКТНЫЕ БАЗОВЫЕ КЛАССЫ, УТИНАЯ ТИПИЗАЦИЯ И ПРОТОКОЛЫ
Мы используем абстрактные базовые классы в этой книге по дидактическим причинам: мы надеемся, что они помогут объяснить, что такое интерфейс абстракции репозитория. В реальной жизни мы порой удаляем абстрактные базовые классы из производственного кода, потому что Python слишком легко их игнорирует и они в конечном счете остаются без поддержки, а в худшем случае вводят в заблуждение. На практике в целях задействования абстракции мы часто просто опираемся на утиную типизацию Python. Для питониста репозиторий — это любой объект, имеющий методы add(thing) и get(id).
Всякий раз, когда мы добавляем новый объект модели предметной области нам нужео будет писать несколько строк кода в классе репозитория, который хотим получить, но взамен получаем простую абстракцию над слоем хранения, который мы контролируем. Паттерн «Репозиторий» позволит легко вносить фундаментальные изменения в способ хранения, и как мы увидим, его легко подделывать для юнит-тестов.
Типичный репозиторий (repository.py)
class SqlAlchemyRepository(AbstractRepository):
def __init__(self, session):
self.session = session
def add(self, batch):
self.session.add(batch)
def get(self, reference):
return self.session.query(model.Batch).filter_by(reference=reference)
def list(self):
return self.session.query(model.Batch).all()