Visitor
先貼一個有代碼例子,且好理解的文章:
http://www.cnblogs.com/shanghaif/archive/2008/12/08/1350417.html
再轉寄一個我認為最形象的解釋。
如果有一棵繼承樹,你要使用某個獨立的對象遍曆這棵樹,並且呼叫樹上某一個共同的方法,那麼你使用iterator。比如這是一棵蘋果樹,你使用一個摘蘋果的杆子把蘋果一個一個摘下來,這就是iterator。
現在你有好幾棵樹,蘋果樹、葡萄樹、酸棗樹等,對每一種果實,你都有不同的杆子,摘取果實。這個時候就可以使用visitor模式。
當然,Java對象都源自Ojbect類,所以原則上所有的對象都來自同一棵樹,以Object為根。這時候不妨假設一棵樹有不同的子樹,或者同一棵樹上有不同的果實。
不使用visitor模式行不行,行。那你就使用Iterator模式,像這樣:
while(it.hasNext()){
Object o = it.next();
if (蘋果 instanceof o){...}
else if(葡萄 instanceof o){...}
。。。
}
這樣好像也沒什麼問題,只是一旦有操作進來,比如要給不同的樹打不同的農藥,就要改寫這個條件轉移。
用了Visitor模式之後呢,奇蹟發生了,你拿出所有的杆子舉到每一個果實那裡,蘋果會自己找到摘蘋果的杆子,讓杆子把自己摘下來,葡萄會找到摘葡萄的杆子,把自己摘下來。
如果有打農藥、授粉等等任務進來,Visitor模式可以允許動態加入一個新的visitor類代表打農藥、授粉等,做到這一點不需要修改代碼。這就是OCP。你把所有的農藥都放到每一個果實跟前,果實就自行找到正確的農藥自己打上。把所有的花粉放到果實跟前,果實就自己找到正確的花粉授粉。
你只有這些種水果杆子/農藥/花粉,如果你有新的水果種類,對不起,只好改寫代碼。Visitor模式不支援這種情況下的OCP。
Template Method
參見:http://blog.csdn.net/hguisu/article/details/7564039
大意是父類負責邏輯組合部分,實現共同的邏輯部分,並把不同子類具有的不同邏輯部分通過protected abstract方法開放出去,由子類負責具體的實現。
在Android中,View的源碼中,draw()方法承擔了邏輯組合的功能,負責所有繪製邏輯的實現。同時View也實現了共同的邏輯部分,如繪製padding,操作matrix等。而不同的子類的不同具體繪製形為是通過實現抽象方法onDraw實現的。