Software Engineering is the application of a systematic, disciplined, quantifiable approach to the development, operation, and maintenance of software, and the study of these approaches; that is, the application of engineering to software...
, a fluent interface (as first coined by Eric Evans and Martin Fowler
Martin Fowler
-Online presentations:* at RailsConf 2006* at JAOO 2006* at QCon London 2007 * at QCon London 2008 * at ThoughtWorks Quarterly Technology Briefing, October 2008...
Object-oriented design is the process of planning a system of interacting objects for the purpose of solving a software problem. It is one approach to software design.-Overview:...
API that aims to provide for more readable code.
A fluent interface is normally implemented by using method chaining
Method chaining
Method chaining is a common technique for invoking multiple method calls in object-oriented programming languages. Each method returns an object , allowing the calls to be chained together in a single statement...
to relay the instruction context of a subsequent call (but a fluent interface entails more than just method chaining ). 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.
This style is marginally beneficial in readability due to its ability to provide a more fluid feel to the code . However, it can be detrimental to debugging, as a fluent chain constitutes a single statement for which debuggers may not allow setting up intermediate breakpoints, for instance.
Delphi (Object Pascal)
The following example shows a class implementing a non-fluent interface, another class implementing a fluent counterpart of the aforementioned non-fluent interface, and differences in usage. The example is written in Delphi Object Pascal:
unit FluentInterface;
IConfigurationFluent = interface
function SetColor(Color: string): IConfigurationFluent;
function SetHeight(height: integer): IConfigurationFluent;
function SetLength(length: integer): IConfigurationFluent;
function SetDepth(depth: integer): IConfigurationFluent;
end;
TConfigurationFluent = class(TInterfacedObject, IConfigurationFluent)
private
FColor: string;
FHeight: integer;
FLength: integer;
FDepth: integer;
protected
function SetColor(Color: string): IConfigurationFluent;
function SetHeight(height: integer): IConfigurationFluent;
function SetLength(length: integer): IConfigurationFluent;
function SetDepth(depth: integer): IConfigurationFluent;
public
class function New: IConfigurationFluent;
end;
implementation
procedure TConfiguration.SetColor(Color: string);
begin
FColor := Color;
end;
procedure TConfiguration.SetDepth(depth: integer);
begin
FDepth := depth;
end;
procedure TConfiguration.SetHeight(height: integer);
begin
FHeight := height;
end;
procedure TConfiguration.SetLength(length: integer);
begin
FLength := length;
end;
class function TConfigurationFluent.New: IConfigurationFluent;
begin
Result := Create;
end;
function TConfigurationFluent.SetColor(Color: string): IConfigurationFluent;
begin
FColor := Color;
Result := Self;
end;
function TConfigurationFluent.SetDepth(depth: integer): IConfigurationFluent;
begin
FDepth := depth;
Result := Self;
end;
function TConfigurationFluent.SetHeight(height: integer): IConfigurationFluent;
begin
FHeight := height;
Result := Self;
end;
function TConfigurationFluent.SetLength(length: integer): IConfigurationFluent;
begin
FLength := length;
Result := Self;
end;
end.
Basic Usage:
var C, D: IConfiguration;
E: IConfigurationFluent;
begin
C := TConfiguration.Create;
C.SetColor('blue');
C.SetHeight(1);
C.SetLength(2);
C.SetDepth(3);
{ same "non-fluent interface" accessed using the "with" statement }
D := TConfiguration.Create;
with D do begin
SetColor('blue');
SetHeight(1);
SetLength(2);
SetDepth(3)
end;
E := TConfigurationFluent.New
.SetColor('Blue')
.SetHeight(1)
.SetLength(2)
.SetDepth(3);
end;
C#
The following example shows a class implementing a non-fluent interface, another class implementing a fluent counterpart of the aforementioned non-fluent interface, and differences in usage. The example is written in C#:
namespace Example.FluentInterfaces
{
#region Standard Example
public static class ExampleProgram
{
public static void Main
{
// Standard Example
IConfiguration config = new Configuration;
config.SetColor("blue");
config.SetHeight(1);
config.SetLength(2);
config.SetDepth(3);
C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features. It was developed by Bjarne Stroustrup starting in 1979 at Bell...
iostream is a header file which is used for input/output in the C++ programming language. It is part of the C++ standard library. The name stands for Input/Output Stream. In C++ and its predecessor, the C programming language, there is no special syntax for streaming data input or output. Instead,...
In object oriented computer programming, operator overloading—less commonly known as operator ad-hoc polymorphism—is a specific case of polymorphism, where different operators have different implementations depending on their arguments...
.
The following is an example of providing a fluent interface wrapper on top of a more traditional interface in C++:
Java is a programming language originally developed by James Gosling at Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ but has a simpler object model and fewer low-level facilities...
The Java Persistence API, sometimes referred to as JPA, is a Java programming language framework managing relational data in applications using Java Platform, Standard Edition and Java Platform, Enterprise Edition....
In object-oriented programming, mock objects are simulated objects that mimic the behavior of real objects in controlled ways. A programmer typically creates a mock object to test the behavior of some other object, in much the same way that a car designer uses a crash test dummy to simulate the...
testing library EasyMock makes extensive use of this style of interface to provide an expressive programming interface.
Collection mockCollection = EasyMock.createMock(Collection.class);
EasyMock.expect(mockCollection.remove(null)).andThrow(new NullPointerException).atLeastOnce;
Another Java Example
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.
GridBagLayout gl = new GridBagLayout;
JPanel p = new JPanel;
p.setLayout( gl );
JLabel l = new JLabel("Name:");
JTextField nm = new JTextField(10);
This creates a lot of code and makes it difficult to see what exactly is happening here. The Packer class, visible at http://packer.dev.java.net, provides a Fluent mechanism for using this class so that you would instead write:
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.
PHP
The following is an example of a class with a fluent interface implemented in PHP
PHP
PHP is a general-purpose server-side scripting language originally designed for web development to produce dynamic web pages. For this purpose, PHP code is embedded into the HTML source document and interpreted by a web server with a PHP processor module, which generates the web page document...
:
class Car {
private $speed;
private $color;
private $doors;
public function setSpeed($speed) {
$this->speed = $speed;
return $this;
}
public function setColor($color) {
$this->color = $color;
return $this;
}
public function setDoors($doors) {
$this->doors = $doors;
return $this;
}
}
// Fluent interface
$myCar = new Car;
$myCar->setSpeed(100)->setColor('blue')->setDoors(5);
// Example without fluent interface
$myCar2 = new Car;
$myCar2->setSpeed(100);
$myCar2->setColor('blue');
$myCar2->setDoors(5);
Actionscript 3
The following is an example of a class with a fluent interface implemented in Actionscript
ActionScript
ActionScript is an object-oriented language originally developed by Macromedia Inc. . It is a dialect of ECMAScript , and is used primarily for the development of websites and software targeting the Adobe Flash Player platform, used on Web pages in the form of...
:
package example.fluentinterface
{
public class Configuration
{
private var _color:String;
private var _depth:int;
private var _height:int;
private var _length:int;
public function Configuration
{
}
public static function create:Configuration
{
return new Configuration;
}
public function setColor(value:int):Configuration
{
this._color = value;
return this;
}
public function setDepth(value:int):Configuration
{
this._depth = value;
return this;
}
public function setHeight(value:int):Configuration
{
this._height = value;
return this;
}
public function setLength(value:int):Configuration
{
this._length = value;
return this;
}
}
}
public class Main
{
public function Main:void
{
// Standard Example
var config:Configuration = new Configuration;
config.setColor("blue");
config.setHeight(1);
config.setLength(2);
config.setDepth(3);
// Fluent Example
var fluentConfig:Configuration = Configuration
.create
.setColor("blue")
.setHeight(1)
.setLength(2)
.setDepth(3);
}
}
}
JavaScript
The following is an example of a class with a fluent interface implemented in JavaScript
JavaScript
JavaScript is a prototype-based scripting language that is dynamic, weakly typed and has first-class functions. It is a multi-paradigm language, supporting object-oriented, imperative, and functional programming styles....
:
var Car = function{
var speed, color, doors, pub;
function setSpeed(new_speed) {
speed = new_speed;
return pub;
}
function setColor(new_color) {
color = new_color;
return pub;
}
function setDoors(new_doors) {
doors = new_doors;
return pub;
}
// Example without fluent interface
myCar2 = Car;
myCar2.setSpeed(100);
myCar2.setColor('blue');
myCar2.setDoors(5);
The following is a more concise code for the above example of a JavaScript
JavaScript
JavaScript is a prototype-based scripting language that is dynamic, weakly typed and has first-class functions. It is a multi-paradigm language, supporting object-oriented, imperative, and functional programming styles....
class with a fluent interface.
var Car = function {