流式介面（fluent interface）是軟體工程中面向物件 API 的一種實現方式，以提供更為可讀的原始碼。最早由與 Martin Fowler 於 2005 年提出。 通常採取 具體說是方法鏈式呼叫 來轉發一系列物件方法呼叫的上下文 。這個上下文（context）通常是指： 透過被調方法的返回值定義 自引用，新的上下文等於老的上下文。 返回一個空的上下文來終止。 C 的 iostream 流式呼叫就是一個典型的例子。Smalltalk 在 1970 年代就實現了。 例子 JavaScript 用於資料庫查詢的 jQuery，例如 httpsgithubcomMediumdynamite getting an item from a table clientgetItem usertable setHashKey userId userA setRangeKey column execute then function data dataresult the resulting object JavaScript 使用原型繼承與 this example from httpschiercopostmethodchaininginjavascript define the class var Kitten function thisname Garfield thiscolor brown thisgender male KittenprototypesetName function name thisname name return this KittenprototypesetColor function color thiscolor color return this KittenprototypesetGender function gender thisgender gender return this Kittenprototypesave function consolelog saving thisname the thiscolor thisgender kitten save to database here return this use it new Kitten setName Bob setColor black setGender male save Java jOOQ 庫模擬了 SQL Author author AUTHORas author createselectFrom author where exists selectOne from BOOK where BOOKSTATUSeq BOOK_STATUSSOLD_OUT and BOOKAUTHOR_IDeq authorID C C 在 LINQ 中大量使用 standard query operators 與擴充套件方法。 var translations new Dictionarystring string cat chat dog chien fish poisson bird oiseau Find translations for English words containing the letter a sorted by length and displayed in uppercase IEnumerablestring query translations Where t tKeyContains a OrderBy t tValueLength Select t tValueToUpper The same query constructed progressively var filtered translationsWhere t tKeyContains a var sorted filteredOrderBy t tValueLength var finalQuery sortedSelect t tValueToUpper 流式介面可用於一系列方法，他們執行在同一物件上。 Defines the data context class Context public string FirstName get set public string LastName get set public string Sex get set public string Address get set class Customer private Context _context new Context Initializes the context set the value for properties public Customer FirstName string firstName _contextFirstName firstName return this public Customer LastName string lastName _contextLastName lastName return this public Customer Sex string sex _contextSex sex return this public Customer Address string address _contextAddress address return this Prints the data to console public void Print ConsoleWriteLine First name 0 nLast name 1 nSex 2 nAddress 3 _contextFirstName _contextLastName _contextSex _contextAddress class Program static void Main string args Object creation Customer c1 new Customer Using the method chaining to assign print data with a single line c1FirstName vinodLastName srivastavSex maleAddress bangalorePrint C 下述程式碼對比了傳統的風格與流式介面的實現風格： Basic definition 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 Basic usage int main int argc char argv GlutApp app argc argv appsetDisplayMode GLUT_DOUBLEGLUT_RGBAGLUT_ALPHAGLUT_DEPTH Set framebuffer params appsetWindowSize 500 500 Set window params appsetWindowPosition 200 200 appsetTitle My OpenGLGLUT App appcreate Fluent wrapper class FluentGlutApp private GlutApp public FluentGlutApp int argc char argv GlutApp argc argv Inherit parent constructor 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 It doesnt make sense to chain after create so dont return this void create GlutAppcreate Fluent usage int main int argc char argv FluentGlutApp argc argv withDoubleBuffer withRGBA withAlpha withDepth at 200 200across 500 500 named My OpenGLGLUT App create Ruby Ruby 語言允許修改核心類，這使得流式介面成為原生易於實現。 Add methods to String class class String def prefix raw raw self end def suffix raw self raw end def indent raw raw raw if rawkind_of Fixnum prefix raw end end Fluent interface message there puts messageprefix hello suffix world indent 8 Scala Scala supports a fluent syntax for both method calls and class mixins using traits and the with keyword For example class Color def rgb Tuple3 Decimal object Black extends Color override def rgb Tuple3 Decimal 0 0 0 trait GUIWindow Rendering methods that return this for fluent drawing def set_pen_color color Color thistype def move_to pos Position thistype def line_to pos Position end_pos Position thistype def render thistype this Dont draw anything just return this for child implementations to use fluently def top_left Position def bottom_left Position def top_right Position def bottom_right Position trait WindowBorder extends GUIWindow def render GUIWindow superrender move_to top_left set_pen_color Black line_to top_right line_to bottom_right line_to bottom_left line_to top_left class SwingWindow extends GUIWindow val appWin new SwingWindow with WindowBorder appWinrender Perl 6 In Perl 6 there are many approaches but one of the simplest is to declare attributes as readwrite and use the given keyword The type annotations are optional but the native gradual typing makes it much safer to write directly to public attributes class Employee subset Salary of Real where 0 subset NonEmptyString of Str where S at least one nonspace character has NonEmptyString name is rw has NonEmptyString surname is rw has Salary salary is rw method gist return qqto END Name name Surname surname Salary salary END my employee Employeenew given employee name Sally surname Ride salary 200 say employee Output Name Sally Surname Ride Salary 200 PHP 在 PHP 中，可以使用表示例項的特殊變數 this 返回當前物件。因此返回 this 將使方法返回例項。下面的示例定義了一個 Employee 類和三個方法來設定它的名稱、姓和薪水。每個 Employee 類的例項允許呼叫這些方法。 php class Employee public name public surName public salary public function setName name thisname name return this public function setSurname surname thissurName surname return this public function setSalary salary thissalary salary return this public function __toString employeeInfo Name thisname PHP_EOL employeeInfo Surname thissurName PHP_EOL employeeInfo Salary thissalary PHP_EOL return employeeInfo Create a new instance of the Employee class Tom Smith with a salary of 100 employee new Employee setName Tom setSurname Smith setSalary 100 Display the value of the Employee instance echo employee Display Name Tom Surname Smith Salary 100 Python Python 透過在例項方法中返回 self： class Poem object def __init__self content selfcontent content def indent self spaces selfcontent spaces selfcontent return self def suffix self content selfcontent selfcontent content return self Poem Road Not Travelledindent 4suffix Robert Frostcontent Road Not Travelled Robert Frost Visual BasicNet 參考文獻 外部連結 Martin Fowlers original bliki entry coining the term A Delphi example of writing XML with a fluent interface A NET fluent validation library written in C A tutorial for creating formal Java fluent APIs from a BNF notation Category 軟體設計模式 CategoryC