Płynne API (Fluent Interface)¶
Wprowadzenie¶
Płynne API (ang. fluent interface) to sposób projektowania interfejsów programistycznych (API), który umożliwia łańcuchowe wywoływanie metod (method chaining). Celem jest zwiększenie czytelności kodu oraz nadanie mu formy przypominającej zdania w języku naturalnym. :contentReference[oaicite:0]{index=0}
Wzorzec ten został spopularyzowany przez Erica Evansa i Martina Fowlera (ok. 2005) i jest szeroko stosowany m.in. w bibliotekach LINQ czy ORM. :contentReference[oaicite:1]{index=1}
Podstawowa idea¶
Każda metoda: - modyfikuje stan obiektu lub - ustawia parametr konfiguracji
i zwraca ten sam obiekt (`self`), co pozwala kontynuować wywołania.
Przykład (bez Fluent API):
ax = Axes(0, 0, 100, 100)
ax.set_xrange(0, 10)
ax.set_yrange(-1, 1)
Z Fluent API:
ax = Axes(0, 0, 100, 100) \
.bottom(0, 10) \
.left(-1, 1)
Kod staje się krótszy i bardziej deklaratywny.
Kluczowe zasady projektowe¶
Metody zwracają
self
def bottom(self, xmin, xmax):
self.xmin = xmin
self.xmax = xmax
return self
Zachowanie kontekstu
Każde kolejne wywołanie operuje na tym samym obiekcie (tym samym stanie).
Czytelność jako DSL (Domain-Specific Language)
Kod powinien przypominać „zdanie”:
Axes(...).bottom(0, 10).left(-1, 1).with_grid(True)
Opcjonalne zakończenie łańcucha
Czasem stosuje się metodę end() jako sygnał końca konfiguracji:
ax = Axes(...).bottom(...).left(...).end()
Zastosowanie w klasie Axes¶
W zadaniu projektowym klasa Axes pełni rolę konfiguratora układu współrzędnych.
Fluent API pozwala oddzielić:
konstrukcję obiektu (geometria)
konfigurację (zakresy, styl, siatka)
Przykład docelowy:
axes = (
Axes(80, 40, 580, 260)
.bottom(0.0, 6.28)
.left(-1.0, 1.0)
.with_xticks(6)
.with_yticks(4)
.with_grid(True)
.end()
)
Warto zwrócić uwagę:
metody nie tworzą nowych obiektów → modyfikują istniejący
kolejność wywołań ma znaczenie semantyczne
API powinno być spójne (np.
bottom/top,left/right)
Typowe błędy¶
Brak
return self
def bottom(self, xmin, xmax):
self.xmin = xmin
self.xmax = xmax
# brak return → łańcuch się psuje
Niespójne nazewnictwo
Złe:
.set_xrange(...).grid_on(True)
Dobre:
.bottom(...).with_grid(True)
Zbyt długa logika w metodach
Metody fluent powinny być proste i jednofunkcyjne.
Uwagi projektowe¶
Fluent API poprawia czytelność, ale może utrudniać debugowanie (łańcuch wielu wywołań w jednej linii).
Dobrą praktyką jest łamanie łańcucha na wiele linii.
W Pythonie implementacja jest naturalna dzięki zwracaniu
self.