Паттерн Строитель отделяет построение сложного объекта от его итоговой формы. Вместо одного конструктора с множеством параметров вы вызываете маленькие именованные шаги и завершаете build(). Он полезен, когда у объекта много необязательных частей, он собирается за несколько шагов или должен проверяться целиком.
Телескопический конструктор
Чтобы задать последний необязательный параметр, нужно передать все предыдущие. Вызов Request("GET", "/users", None, {"page": 2}, None, 10, 3) нечитаем, а перестановка 10 и 3 не даёт ошибки.
class Request:
def __init__(self, method, url, headers=None, params=None,
body=None, timeout=30, retries=0):
self.method, self.url = method, url
self.headers = headers or {}
self.params = params or {}
self.body = body
self.timeout, self.retries = timeout, retries
def __repr__(self):
return (f"{self.method} {self.url} params={self.params} "
f"timeout={self.timeout} retries={self.retries}")
print(Request("GET", "/users", None, {"page": 2}, None, 10, 3))GET /users params={'page': 2} timeout=10 retries=3Пошаговое построение с текучим интерфейсом
Каждый шаг сохраняет часть и возвращает self, поэтому вызовы собираются в «предложение». build() создаёт продукт, здесь строку SQL с кортежем параметров. Значения передаются заполнителями ? и никогда не склеиваются в SQL.