Method chaining

Method chaining, also known as named parameter idiom, is a common syntax 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.[1] Chaining is syntactic sugar which eliminates the need for intermediate variables. A method chain is also known as a train wreck due to an increasing amount of methods stacked one after another in one line,[2] though often line breaks are added between methods.

A similar syntax is method cascading, where after the method call the expression evaluates to the current object, not the return value of the method. Cascading can be implemented using method chaining by having the method return the current object itself (this). Cascading is a key technique in fluent interfaces, and since chaining is widely implemented in object-oriented languages while cascading isn't, this form of "cascading-by-chaining by returning this" is often referred to simply as "chaining". Both chaining and cascading come from the Smalltalk language.

While chaining is syntax, it has semantic consequences, namely that requires methods to return an object, and if implementing cascading via chaining, this must be the current object. This prevents the return value from being used for some other purpose, such as returning an error value, and requires that the return value be mutable (e.g., the original object, not a copy).

Examples[edit]

Java[edit]

The following is an example in Java of how method chaining might be implemented and used:

class Person {
	private String name;
	private int age;
 
        // In addition to having the side-effect of setting the attributes in question,
        // the setters return "this" (the current Person object) to allow for further chained method calls.
 
	public Person setName(String name) {
		this.name = name;
		return this;
	}
 
	public Person setAge(int age) {
		this.age = age;
		return this;
	}
 
	public void introduce() {
		System.out.println("Hello, my name is " + name + " and I am " + age + " years old.");
	}
 
	// Usage:
	public static void main(String[] args) {
		Person person = new Person();
		// Output: Hello, my name is Peter and I am 21 years old.
		person.setName("Peter").setAge(21).introduce();
	}
}

By contrast, here is a non-chained equivalent:

class Person {
	private String name;
	private int age;
 
        // Per normal Java style, the setters return void.
 
	public void setName(String name) {
		this.name = name;
	}
 
	public void setAge(int age) {
		this.age = age;
	}
 
	public void introduce() {
		System.out.println("Hello, my name is " + name + " and I am " + age + " years old.");
	}
 
	// Usage:
	public static void main(String[] args) {
		Person person = new Person();
                // Not using chaining; longer than the chained version above.
		// Output: Hello, my name is Peter and I am 21 years old.
		person.setName("Peter");
                person.setAge(21);
                person.introduce();
	}
}

jQuery[edit]

jQuery heavily relies on chaining. This makes it easy to call several methods on the same selection. It also makes code more clear and prevents executing the same selection several times (hence improving performance). The following code exemplifies only its usage (and not its implementation which is in charge of jQuery):

// chaining
$("#person").slideDown('slow')
   .addClass('grouped')
   .css('margin-left', '11px');
// no chaining
$('#person').slideDown('slow');
$('#person').addClass('grouped');
$('#person').css('margin-left', '11px');

C++[edit]

The named parameter idiom can be expressed in C++ as follows:

#include <string>
#include <iostream>
 
class Person
{
    std::string m_name;
    int m_age;
 
public:
    Person &name(std::string const &name) {this->m_name = name; return *this;}
    Person &age(int const age) {this->m_age = age; return *this;}
 
    friend std::ostream & operator << (std::ostream &os, Person const &);
};
 
 
std::ostream & operator << (std::ostream &os, Person const &person)
{
    return os << "Hello, my name is " << person.m_name << " and I am " << person.m_age << " years old.";
}
 
 
int main(void)
{
    Person person;
    std::cout << person.name("Peter").age(21) << std::endl;
 
    return 0;
}

Ruby[edit]

In Ruby, the named parameter idiom can be expressed as follows:

class Person
 
  def name(value)
    @name = value
    self
  end
 
  def age(value)
    @age = value
    self
  end
 
  def introduce
    puts "Hello, my name is #{@name} and I am #{@age} years old."
  end
 
end
 
person = Person.new
person.name("Peter").age(21).introduce
# => Hello, my name is Peter and I am 21 years old.

PHP[edit]

Implementation and usage of method chaining in PHP:

<?php
 
class Person {
 
  protected $name;
  protected $age;
 
  public function setName($name) {
    $this->name = $name;
    return $this;
  }
 
  public function setAge($age) {
    $this->age = $age;
    return $this;
  }
 
  public function __toString() {
    return "Hello, my name is ".$this->name." and I am ".$this->age." years old.";
  }
}
 
$person = new Person;
echo $person->setName("Peter")->setAge(21), "\n";

Python[edit]

class Person:
    def name(self, value):
        self.name = value
        return self
 
    def age(self, value):
        self.age = value
        return self
 
    def introduce(self):
        print "Hello, my name is", self.name, "and I am", self.age, "years old."
 
person = Person()
person.name("Peter").age(21).introduce()
# => Hello, my name is Peter and I am 21 years old.

Io[edit]

Person := Object clone do(
# ::= operator creates a setter which can be used in method chaining
	name ::= "Unknown" 
	age ::= 0
	introduce := method(
		"Hello, my name is #{self name} and I'm #{self age} years old" interpolate println
	)
)
 
 
person := Person clone
person setName("Peter") setAge(21) introduce

See also[edit]

References[edit]

  1. Jump up^ "Applying Method Chaining"http://firstclassthoughts.co.uk/: First Class Thoughts. Retrieved 2011-04-13. "In order to simplify repeated object interactions on the same object the old trick Method Chaining originating the world of Smalltalk should be enforced. The idea is to let methods return this rather than void, thus affecting especially set() and add() methods. Method chaining arose during the designers of Smalltalk pursuit to minimize the number of keywords in the language, which lead to the discovery that void is an unnecessary keyword!."
  2. Jump up^ Martin, Robert Cecil (2008). Clean Code: A Handbook of Agile Software CraftsmanshipPrentice HallISBN 0-13-235088-2.

External links[edit]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值