方法鏈

方法鏈(Method Chaining),也被稱為命名參數法,是在面向對象的程式語言中調用的調用多個方法的通用語法。每一個方法返回一個對象,在一個單一的聲明里,方法鏈省去了中間變數的需要。

基本介紹

  • 中文名:方法鏈
  • 外文名:Method Chaining
  • 別稱:命名參數法
  • 套用領域:計算機等
  • 套用對象:程式語言
  • 特徵:每一個方法返回一個對象
簡介,方法鏈的優勢,Python中方法鏈的套用,jQuery中方法鏈的套用,Javascript中方法鏈的套用,

簡介

方法鏈(method chaining)是面向對象的程式語言中的一種常見語法,可以讓開發者在只引用對象一次的情況下,對同一個對象進行多次方法調用。
舉個例子:
假設我們有一個Foo類,其中包含有兩個方法——bar和baz。
我們創建一個Foo類的實例:
1
foo = Foo()
如果不使用方法鏈,要想連續調用對象foo的bar和baz方法的話,我們得這樣做:
1
2
foo.bar() # Call method bar() on object foo.
foo.baz() # Call method baz() on object foo.
如果使用方法鏈的話,我們就能這樣實現: foo.bar().baz()

方法鏈的優勢

方法鏈的一個好處,是可以減少你使用對象名的次數。調用的方法越多,能夠減少的次數就越多。因此,這個方法也能一定程度上減少需要閱讀、測試、調試、維護的代碼數量。這個好處不大,但也是有用的。
1. 讓調用過程更接近自然語言。
2. 把原本參數列表複雜的方法化作多個參數列表簡單的方法來使用。
3. 減少不必要的代碼量。
這個三點都是有益於開發的,所以方法鏈的存在很有意義。
請注意,方法鏈的一個限制是,只能用在不需要返回其他值的方法上,因為你需要返回self對象。即使Python支持用一個return語句返回多個值,也可能無法解決這個問題。

Python中方法鏈的套用

下面是在Python中實現方法鏈的一個示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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("EarlGrey").age(21).introduce()
# => Hello, my name is EarlGrey and I am 21 years old.
上面那種實現可能太簡單了。更加現實的方法鏈使用方法:編寫一個字元串處理程式string_processor.py,支持方法鏈。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import copy
class StringProcessor(object):
'''
A class to process strings in various ways.
'''
def __init__(self, st):
'''Pass a string for st'''
self._st = st
def lowercase(self):
'''Make lowercase'''
self._st = self._st.lower()
return self
def uppercase(self):
'''Make uppercase'''
self._st = self._st.upper()
return self
def capitalize(self):
'''Make first char capital (if letter); make other letters lower'''
self._st = self._st.capitalize()
return self
def delspace(self):
'''Delete spaces'''
self._st = self._st.replace(' ', '')
return self
def rep(self):
'''Like Python's repr'''
return self._st
def dup(self):
'''Duplicate the object'''
return copy.deepcopy(self)
def process_string(s):
print
sp = StringProcessor(s)
print 'Original:', sp.rep()
print 'After uppercase:', sp.dup().uppercase().rep()
print 'After lowercase:', sp.dup().lowercase().rep()
print 'After uppercase then capitalize:', sp.dup().uppercase().\
capitalize().rep()
print 'After delspace:', sp.dup().delspace().rep()
def main():
print "Demo of method chaining in Python:"
# Use extra spaces between words to show effect of delspace.
process_string('hOWz It GoInG?')
process_string('The QUIck brOWn fOx')
main()
下面是這個程式的運行結果:
1
2
3
4
5
6
7
8
9
10
11
12
13
$ python string_processor.py
Original: hOWz It GoInG?
After uppercase: HOWZ IT GOING?
After lowercase: howz it going?
After uppercase then capitalize: Howz it going?
After delspace: hOWzItGoInG?
Original: The QUIck brOWn fOx
After uppercase: THE QUICK BROWN FOX
After lowercase: the quick brown fox
After uppercase then capitalize: The quick brown fox
After delspace: TheQUIckbrOWnfOx
綜上,我們可以發現,方法鏈有其用處,不過過度使用可能不太好。

jQuery中方法鏈的套用

目測對於方法鏈用得最多的,應該就是jQuery了。
代碼如下:
// chaining
$("#person").slideDown('slow')
.addClass('grouped')
.css('margin-left', '11px');
我們可以用這樣的用法來調用這個。
jQuery嚴重依賴於連結。這使得它很容易調用的幾個方法相同的選擇。這也使得代碼更清晰和防止執行相同的選擇幾次(提高性能)。沒有方法鏈的時候則是下面的樣子
代碼如下:
var p = $('#person');
p.slideDown('slow');
p.addClass('grouped');
p.css('margin-left', '11px');
看上去和設計模式中的builder很像,不同的是,這裡的p是方法,而不是一個類。

Javascript中方法鏈的套用

Javascript方法鏈示例
在之前我們說到Javascript高階函式的時候,說到的print('Hello')('World'),而這種用法的結果可能會變成這樣子。
代碼如下:
function f(i){
return function(e){
i+=e;
return function(e){
i+=e;
return function(e){
alert(i+e);
};
};
};
};
f(1)(2)(3)(4); //10
代碼如下:

var func = (function() {
return{
add: function () {
console.log('1');
return{
result: function () {
console.log('2');
}
}
}
}
})();
func.add().result();

實際上應該在每個function都要有個return this,於是就有了:

Func = (function() {
this.add = function(){
console.log('1');
return this;
};
this.result = function(){
console.log('2');
return this;
};
return this;
});
var func = new Func();
func.add().result();

可以將最後的兩句
var func = new Func();
func.add().result();
變成
new Func().add().result();
其他
最後作為一個迷惑的地方的小比較:
Method Chaining VS prototype Chaining
原型鏈與方法鏈在某些方面上是差不多的,不同的地方或許在於
  1. 原型鏈是需要用原型
  2. 方法鏈則是用方法

相關詞條

熱門詞條

聯絡我們