Fluent interface

简介:

In software engineering, a fluent interface (as first coined by Eric Evans and Martin Fowler) is an implementation of an object oriented API that aims to provide for more readable code.

A fluent interface is normally implemented by using method cascading (concretely method chaining) to relay the instruction context of a subsequent call (but a fluent interface entails more than just method chaining [1]). Generally, the context is

  • defined through the return value of a called method
  • self-referential, where the new context is equivalent to the last context
  • terminated through the return of a void context.

 

History[edit]

The term "fluent interface" was coined in late 2005, though this overall style of interface dates to the invention of method cascading in Smalltalk in the 1970s, and numerous examples in the 1980s. The most familiar is the iostream library in C++, which uses the << or >>operators for the message passing, sending multiple data to the same object and allowing "manipulators" for other method calls. Other early examples include the Garnet system (from 1988 in Lisp) and the Amulet system (from 1994 in C++) which used this style for object creation and property assignment.

 

Examples[edit]

Java[edit]

The jOOQ library models SQL as a fluent API in Java

1
2
3
4
5
6
Author a = AUTHOR.as( "a" );
create.selectFrom(a)
       .where(exists(selectOne()
                    .from(BOOK)
                    .where(BOOK.STATUS.eq(BOOK_STATUS.SOLD_OUT))
                    .and(BOOK.AUTHOR_ID.eq(a.ID))));

  

The op4j library enables the use of fluent code for performing auxiliary tasks like structure iteration, data conversion, filtering, etc.

1
2
3
4
String[] datesStr =  new  String[] { "12-10-1492" "06-12-1978" };
...
List<Calendar> dates =
     Op.on(datesStr).toList().map(FnString.toCalendar( "dd-MM-yyyy" )).get();

  

The fluflu annotation processor enables the creation of a fluent API using Java annotations.

Also, the mock object testing library EasyMock makes extensive use of this style of interface to provide an expressive programming interface.

1
2
Collection mockCollection = EasyMock.createMock(Collection. class );
EasyMock.expect(mockCollection.remove( null )).andThrow( new  NullPointerException()).atLeastOnce();

  

In the Java Swing API, the LayoutManager interface defines how Container objects can have controlled Component placement. One of the more powerful LayoutManager implementations is the GridBagLayout class which requires the use of the GridBagConstraints class to specify how layout control occurs. A typical example of the use of this class is something like the following.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
GridBagLayout gl =  new  GridBagLayout();
JPanel p =  new  JPanel();
p.setLayout( gl );
  
JLabel l =  new  JLabel( "Name:" );
JTextField nm =  new  JTextField( 10 );
  
GridBagConstraints gc =  new  GridBagConstraints();
gc.gridx =  0 ;
gc.gridy =  0 ;
gc.fill = GridBagConstraints.NONE;
p.add( l, gc );
  
gc.gridx =  1 ;
gc.fill = GridBagConstraints.HORIZONTAL;
gc.weightx =  1 ;
p.add( nm, gc );

  

This creates a lot of code and makes it difficult to see what exactly is happening here. The Packer class, visible at http://java.net/projects/packer/, provides a Fluent mechanism for using this class so that you would instead write:

1
2
3
4
5
6
7
8
JPanel p =  new  JPanel();
Packer pk =  new  Packer( p );
  
JLabel l =  new  JLabel( "Name:" );
JTextField nm =  new  JTextField( 10 );
  
pk.pack( l ).gridx( 0 ).gridy( 0 );
pk.pack( nm ).gridx( 1 ).gridy( 0 ).fillx();

  

There are many places where Fluent APIs can greatly simplify how software is written and help create an API language that helps users be much more productive and comfortable with the API because the return value of a method always provides a context for further actions in that context.

目录
相关文章
|
2月前
|
C#
C# 接口(Interface)
接口定义了所有类继承接口时应遵循的语法合同。接口定义了语法合同 "是什么" 部分,派生类定义了语法合同 "怎么做" 部分。 接口定义了属性、方法和事件,这些都是接口的成员。接口只包含了成员的声明。成员的定义是派生类的责任。接口提供了派生类应遵循的标准结构。 接口使得实现接口的类或结构在形式上保持一致。 抽象类在某种程度上与接口类似,但是,它们大多只是用在当只有少数方法由基类声明由派生类实现时。 接口本身并不实现任何功能,它只是和声明实现该接口的对象订立一个必须实现哪些行为的契约。 抽象类不能直接实例化,但允许派生出具体的,具有实际功能的类。
49 9
|
7月前
|
Java
接口(interface)
接口(interface)
|
Java 编译器 开发工具
@interface的用法
@interface的用法
接口(interface)
接口是Java语言中一种引用类型,是方法的集合,如果说类的内部封装了成员变量、构造方法和成员方法,那么接口的内部主要就是封装了方法,包含抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法(JDK 9)。最重要的就是其中的抽象方法
|
网络虚拟化 网络协议 ARouter