ЧАСТЬ 2. Helper Pattern
В предыдущей части, мы рассматривали условный Handler Pattern, который должен был решить проблемы паттерна о котором мы будем говорить в этой части.
Повторюсь в рамках постов про архитектуру, названия паттернам я придумал самостоятельно, не отрицаю, что где-то на просторах интернета есть более правильные названия.
Так вот, в этом подходе мы выносим необходимую подготовку в классы помощники, тем самым появляется удобный способ переиспользования ранее написанных методов.
Например:
Сначала реализуются классы для необходимых API клиентов.
# first_client.py
class FirstApiClient:
def some_post_handler(self, **kwargs) -> FirstObject:
# Логика отправки запроса
return FirstObject()
def some_put_handler(self, **kwargs) -> PutObject:
# Логика отправки запроса
return PutObject()
# second_client.py
class SecondApiClient:
def some_get_handler(self, **kwargs) -> Any:
# Логика отправки запроса
return SecondObject()
Дальше пишем класс помощник, в котором реализуются методы упрощающие интерфейс работы с API клиентами, или предоставляющие более простой интерфейс объединяющий несколько шагов.
# helper.py
class SomeHelper:
def __init__(self, first_api_client, second_api_client):
self.first_api_client = first_api_client
self.second_api_client = second_api_client
def prepare_data(self) -> SomeValue:
first_object = self.first_api_client.some_post_handler(**kwargs)
second_object =self.second_api_client.some_get_handler(**kwargs)
return SomeValue(**first_object, **second_object)
Теперь производим инициализацию клиентов, и класса помощника где фикстуры являются довольно удобным способом.
python
# conftest.py
@pytest.fixture
def first_api_client() -> FirstApiClient:
return FirstApiClient()
@pytest.fixture
def second_api_client() -> SecondApiClient:
return SecondApiClient()
@pytest.fixture
def helper(first_api_client, second_api_client) -> SomeHelper:
return SomeHelper(first_api_client, second_api_client)
Сам тест у нас выглядит так.
python
# test_some_put_handler.py
def test_some_put_handler(helper):
data = helper.prepare_data()
response = helper.first_api_client.some_put_handler(**data)
assert response.json()["value"] == "some_value"
Плюсы:
1. Удобное переиспользование функций, достаточно использовать необходимый класс помощник
2. Удобное масштабирование, мы можем делать классы помощники в зависимости от доменной области например UserHelper, ProductHelper, OrderHelper и т.д.
3. Удобная сборка, класс помощник можно собирать, как конструктор передавая нужные клиенты
4. Лаконичные и читаемые тесты, вся логика инкапсулируется внутри классов помощников и оберток
5. Модульность, понятность и прозрачность кода и архитектуры
Минусы:
1. На большом проекте классы помощники могут разрастаться до нескольких тысяч строк кода
2. Паттерн порождает большое количество фикстур (Но эта проблема решаема)
Исходя из количества плюсов, которые я написал наверняка можно понять, что это мой любимый паттерн и его я использую на проектах.
Пишите минусы которые я не написал в тредик, буду благодарен и добавлю в пост)
TG-сообщество | Обучение |Отзывы
