故事
10月20日, 我們公司一行幾人參加紹興客戶的專案招標。出乎意料的是,就在當天,這家單位同時舉行三個專案的招標(真牛!),所以十幾家單位都在等候。我們上午8:30就到了現場,而我們投標的專案去排在下午進行。傻坐了一會,我們提議到魯迅故居去看看。其實幾次去紹興出差都匆匆忙忙的,今天終於如願以償。
近來確實鍛鍊太少,幾個小時下來,我的腳又酸又痛,已經累得走不動了。不過,其中兩幅圖給我深刻的印象。一幅是三維立體效果的紹興古城圖,講述著許多動人的故事;另一幅是周氏家族圖,象一棵參天大樹一樣,枝枝蔓蔓。可以看出,魯迅家族是浙江紹興會稽縣的乙個大家族。魯迅,原名周樹人,他還有兩個兄弟(周建人和周作人),他的父親叫周伯宜,他有個兒子叫周海嬰······,不說不了,再說就快暈了。
我在想乙個可笑的問題,在整個周氏家族裡,誰最能生兒子啊? 當然,我們沒有這麼多時間從頭至尾數一遍。那麼,就讓我們用程式來解決吧。
復合模式(composite)的解決方案
復合模式又叫部分-整體模式(part-whole)。將物件組織成樹型結構(周氏家族圖),可以用來描述整體與部分的關係,使客戶端將單純元素與復合元素同等看待,以此遍歷樹結構所有元素(所有周氏人)。復合模式需要定義三個物件:
抽象介面(ielement):這是乙個抽象類/介面,它給所有物件定義介面,提供操作行為,如statsons方法統計有多少個兒子。
組合(composite)物件:代表包含子元素的組合。
元素(element)物件:代表子元素物件。乙個子元素沒有下級子物件。
抽象介面如下:
namespace
lufamily
void
add(ielement t);
void
remove(ielement t);
void
statsons();}}
組合物件如下:
namespace
lufamily
set}
public
void
add(ielement t)
void
remove(ielement t)
void
statsons()}}
元素物件如下:
namespace
lufamily
set}
public
void
add(ielement t)
void
remove(ielement t)
void
statsons()}}
客戶端呼叫如下:
composite root
=new
composite();
root.name="
周伯宜"
;element e1
=new
element();
e1.name="
周建人"
;root.add(e1);
element e2
=new
element();
e2.name="
周作人"
;root.add(e1);
composite c1
=new
composite();
c1.name="
周樹人"
;root.add(c1);
element e3
=new
element();
e3.name="
周海嬰"
;c1.add(e3);
root.statsons();
也許您會問,既然元素物件(element)沒有下級子物件,為什麼還要實現add和remove方法呢?其實主要是為了實現客戶端對元素物件與組合物件統一對待,而不必區分哪個是元素物件,哪個是組合物件,這是復合模式兩種形式其中之一,即透明復合模式。採用這種方式的缺點是不夠安全,因為在實際應用中,元素物件與組合物件存在著本質區別。
復合模式的另一種形式自然是安全復合模式。採用安全復合模式就是把元素物件與組合物件的在本質上區分開來。即元素物件不需要提供add和remove等元素集合的管理方法。讓我們來看看安全復合模式的實現方法。
抽象介面如下:
namespace
lufamily
void
statsons();}}
組合物件如下:
namespace
lufamily
set}
public
void
add(ielement t)
void
remove(ielement t)
void
statsons()}}
元素物件如下:
namespace
lufamily
set}
void
statsons()}}
客戶端呼叫如下:
composite root
=new
composite();
root.name="
周伯宜"
;element e1
=new
element();
e1.name="
周建人";if
(root
iscomposite)
root.add(e1);
element e2
=new
element();
e2.name="
周作人";if
(root
iscomposite)
root.add(e1);
composite c1
=new
composite();
c1.name="
周樹人";if
(root
iscomposite)
root.add(c1);
element ce1
=new
element();
ce1.name="
周海嬰";if
(c1
iscomposite)
c1.add(ce1);
root.statsons();
為了安全起見,執行add方法的時候,最好判斷是否為組合物件。
設計模式系列漫談之七 命令模式
小雪的故事暫停,欲知後事如何,請等下回再編!現在改編另乙個故事。故事 小時候,我夢想自己成為一名真正的軍人,對軍營生活充滿著嚮往.軍人的豪氣,軍人的英姿總給人無限遐想。閒暇之餘,我喜歡看看軍事題材的電視劇集,包括 和平年代 歷史的天空 沙場點兵 中國近衛軍 垂直打擊 石破天驚 鐵色高原 今年一部電視...
設計模式系列之八外觀模式
外觀模式 提供了乙個統一的介面,用來訪問子系統的一群介面。外觀定義了乙個高層介面,讓子系統更容易使用。下面通過乙個圖來說明外觀模式的使用,此圖來自於 head first設計模式 一書。從上圖中可以看到,通過乙個統一的facade來呼叫複雜的子系統的類。按我的理解,外觀模式實際上就是抽取一些公共的業...
設計模式系列漫談之十二 職責鏈模式
從牙膏廣告說起 在午茶小憩間,以 成語接龍 形式,通過帥哥美女之口巧妙地把牙齒常見的症狀表達出來,從而突出雲南白藥牙膏的獨特功效。這一極其創意的廣告為雲南白藥贏得了巨大的市場,也使其產品為廣大消費者所熟悉,創造了家喻戶曉的品牌效應。成語接龍是一種人們喜聞樂見的遊戲。就遊戲規則來講非常簡單,即用前乙個...