Python: Объектно-ориентированный дизайн
Теория: Fluent Interface
Fluent Interface или текучий интерфейс — это подход проектирования объектно-ориентированных API. Он симулирует естественный язык, благодаря чему повышает читаемость кода. Этот подход может быть особенно полезным в Python, который известен своей читаемостью и простотой.
В этом уроке мы рассмотрим применение Fluent Interface для повышения читаемости и гибкости кода.
Fluent Interface
Рассмотрим пример обработки коллекций:
Здесь мы строим цепочку вызовов, где каждый метод возвращает объект того же типа, что и первоначальный объект, но в измененной форме. Этот подход позволяет строить цепочки вызовов произвольной длины, что и обозначается термином fluent interface.
Схематически цепочка выглядит так: collection.map(...).reject(...). Это схоже с тем, как работают цепочки вызовов в JavaScript, где такой подход — основной способ строить вычисления на коллекциях.
Fluent Interface упрощает чтение и обработку данных. Для его реализации в Python существуют разные подходы. Начнем с самого простого — использования self.
self
Первый способ создания Fluent Interface основан на возврате self из методов, которые участвуют в построении цепочек. self — ссылка на тот объект, в контексте которого вызывается метод, поэтому его можно возвращать как обычное значение:
У этого способа есть один недостаток — объект изменяется. Это значит, что нельзя взять и просто переиспользовать объект-коллекцию для разных выборок, потому что они начнут накладываться друг на друга.
На практике часто используется другой подход, с которым мы уже познакомились в прошлом курсе. Нужно добавить немного функциональности в ООП — возвращать не self, а создавать новый объект того же типа с обновленной коллекцией:
Теперь каждый вызов возвращает новый объект. Такой код значительно безопаснее в использовании и позволяет без проблем переиспользовать новые коллекции. Изменение одной не приведет к автоматическому изменению всех остальных.
Теперь углубимся и рассмотрим более продвинутый и безопасный способ. Этот метод позволяет создавать новые объекты и сохранять исходные данные без изменений.
self.class
В каждом методе, который участвует в создании текучего интерфейса, последняя строчка всегда содержит один и тот же вызов: Collection(coll). Ее можно записать проще, не дублируя названия класса. Вместо возврата нового экземпляра класса Collection напрямую можно воспользоваться self.
В Python self используется для обозначения текущего экземпляра класса. Когда вызывается self.__class__(coll), создается новый экземпляр текущего класса, что идентично вызову Collection(coll):
Этот прием обеспечивает большую гибкость при наследовании классов, так как self.__class__ всегда ссылается на класс текущего экземпляра, а не на конкретно указанный класс.
Выводы
Применение Fluent Interface может значительно улучшить читаемость и гибкость кода. Однако следует быть осторожным при выборе между изменяемым и неизменяемым вариантами, так как оба подхода имеют свои преимущества и недостатки. Важно выбирать подход в соответствии с требованиями вашего приложения.

.png)


