Fluent interface — Вікіпедія

Fluent interface (біжучий чи текучий інтерфейс) в програмуванні — спосіб конструювання об'єктно-орієнтованого API, в якому читабельність коду є близькою до звичайного прозового тексту. Термін вперше був застосований Еріком Евансом та Мартіном Фаулером. Нижче подано приклад для фреймворку тестування JMock: [1].

mock.expects(once()).method("m").with( or(stringContains("hello"),                                           stringContains("howdy")) ); 

Історія

[ред. | ред. код]

Термін "fluent interface" з'явився в кінці 2005, хоча подібний підхід використовувався в Smalltalk ще в 1970-х, та в інших в 1980-их. Типовим прикладом є бібліотека iostream в мові C++, де використовуються оператори << та >> для передачі повідомлень, багатократної пересилки даних до одного і того самого об'єкта.

Приклади

[ред. | ред. код]

Нижче наведено приклад, де fluent interface обгортка застосована поверх більш традиційного інтерфейсу C++:

Приклад на мові С++
 // Звичайне визначення  class GlutApp {  private:      int w_, h_, x_, y_, argc_, display_mode_;      char **argv_;      char *title_;  public:      GlutApp(int argc, char** argv) {          argc_ = argc;          argv_ = argv;      }      void setDisplayMode(int mode) {          display_mode_ = mode;      }      int getDisplayMode() {          return display_mode_;      }      void setWindowSize(int w, int h) {          w_ = w;          h_ = h;      }      void setWindowPosition(int x, int y) {          x_ = x;          y_ = y;      }      void setTitle(const char *title) {          title_ = title;      }      void create(){;}  };  // Базове використання  int main(int argc, char **argv) {      GlutApp app(argc, argv);      app.setDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_ALPHA|GLUT_DEPTH);      app.setWindowSize(500, 500);      app.setWindowPosition(200, 200);      app.setTitle("My OpenGL/GLUT App");      app.create();  }   // "fluent interface" обгортка   class FluentGlutApp : private GlutApp {  public:      FluentGlutApp(int argc, char **argv) : GlutApp(argc, argv) {}      FluentGlutApp &withDoubleBuffer() {          setDisplayMode(getDisplayMode() | GLUT_DOUBLE);          return *this;      }      FluentGlutApp &withRGBA() {          setDisplayMode(getDisplayMode() | GLUT_RGBA);          return *this;      }      FluentGlutApp &withAlpha() {          setDisplayMode(getDisplayMode() | GLUT_ALPHA);          return *this;      }      FluentGlutApp &withDepth() {          setDisplayMode(getDisplayMode() | GLUT_DEPTH);          return *this;      }      FluentGlutApp &across(int w, int h) {          setWindowSize(w, h);          return *this;      }      FluentGlutApp &at(int x, int y) {          setWindowPosition(x, y);          return *this;      }      FluentGlutApp &named(const char *title) {          setTitle(title);          return *this;      }      // Ланцюжок після create() немає змісту, тому не повертаємо *this      void create() {          GlutApp::create();      }  };  // Використання "fluent interface"  int main(int argc, char **argv) {      FluentGlutApp(argc, argv)          .withDoubleBuffer().withRGBA().withAlpha().withDepth()          .at(200, 200).across(500, 500)          .named("My OpenGL/GLUT App")          .create();  } 

В мові Python використовують повернення `self` в методі.

Приклад на мові Python
class Poem(object):     def __init__(self, content):         self.content = content      def indent(self, spaces):         self.content = " " * spaces + self.content         return self      def suffix(self, content):         self.content = self.content + " - " + content         return self 
>>> Poem("Road Not Travelled").indent(4).suffix("Robert Frost").content '    Road Not Travelled - Robert Frost' 

Примітки

[ред. | ред. код]
  1. FluentInterface [Архівовано 8 березня 2021 у Wayback Machine.], Martin Fowler, 20-12-2005