ruby設計模式之合成模式1 基本的合成模式

2021-09-08 15:51:43 字數 2906 閱讀 8447

前幾天在《戲說設計模式》這篇文章中看到了一段關於組合模式的描述:

composite—mary今天過生日。「我過生日,你要送我一件禮物。」「嗯,好吧,去商店,你自己挑。」「這件t恤挺漂亮,買,這條裙子好看,買,這個包也不錯,買。」「喂,買了三件了呀,我只答應送一件禮物的哦。」「什麼呀,t恤加裙子加包包,正好配成一套呀,小姐,麻煩你包起來。」 「……」,mm都會用composite模式了,你會了沒有?

這個例子還是比較通俗的解釋了合成模式的。

所謂合成模式就是指將物件組織到樹結構中,可以用來描述整體與部分的關係。合成模式就是乙個處理物件的樹結構的模式。合成模式把部分與整體的關係用樹結構表示出來。合成模式使得客戶端把乙個個單獨的成分物件和由他們復合而成的合成物件同等看待。

定義是不是雲霧繚繞讓人看不明白,沒關係再舉例說明。

假設我們要做一塊蛋糕(cake),我們可能會經歷如下的流程:準備麵粉->和麵->發酵->切割->烘焙->加奶油->加黃油等等。於是我們就可以說做蛋糕這個任務是由一系列的子任務,比如切割、烘焙等組合而成。這些子任務又可能又更細粒度的子任務組合而成。

縱觀這些子任務,他們都有一些共同的屬性,比如會花費一定的時間,每個子任務都有自己的名字等等。

再看由這些子任務組合而成的更大的任務。這個大一些的任務本質上也是任務,只不過它是由子任務組合而成,僅此而已。

gof將組合模式描述為:the sum acts like one of the parts。當你需要構造基於繼承關係的物件樹,並且希望你的**將單一物件和組合物件一視同仁時,你最好試試組合模式。

在組合模式總gof將實現統一介面或你需要實現物件樹的基類的物件稱作:component。在我們的蛋糕例子裡,component應該是所有任務的抽象基類。

繼承自component、且無法再進行細粒度細分的類為稱為leaf,這個應該很好理解。

那麼同理leaf的父節點就是composite了,他是更高層級的component。

下面的**演示了composite的具體實現,其實現了我們的做蛋糕流程。

class task

attr_reader :name

def initialize name

@name = name

enddef get_time_required

0.0end

end

class adddryingredientstask < task

def initialize

super 'add dry ingredients'

enddef get_time_required

1.0end

end

class mixtask < task

def initialize

super 'mix that batter up'

enddef get_time_required

3.0end

end

class makebattertask < task

def initialize

super 'make batter'

@sub_tasks =

add_sub_task adddryingredientstask.new

add_sub_task mixtask.new

enddef add_sub_task task

@sub_tasks << task

enddef remove_sub_task

@sub_tasks.delete task

enddef get_time_required

time = 0.0

@sub_tasks.each

time

endend

在上面的**中,我們的component就是task基類。所有的leaf和composite都是繼承自該類。task類實現了統一的介面gettimerequired,表示完成該task需要的時間。

mixtask是leaf,繼承自task且不能進行進一步的細化。

makebattertask是composite。其維護了1個subtasks的子集,所有組成其的子集都儲存在其中。另外其提供了一系列的維護subtasks的方法,如新增1個subtask,移除1個subtask。

下面的**優化了makebattertask類。我們可以直接抽象出composite類。該類的主要任務是維護屬於composite的subtasks。因為我們可能有若干個composite類的例項,因此這樣做是靈活且有效率的。

class compositetask < task

def initialize name

super name

@sub_tasks =

enddef add_sub_task task

@sub_tasks << task

enddef remove_sub_task

@sub_tasks.delete task

enddef get_time_required

time = 0.0

@sub_tasks.each

time

endend

class makebattertask < compositetask

def initialize

super 'make batter'

add_sub_task adddryingredientstask.new

add_sub_task mixtask.new

endend

總的說來合成模式適合表示整體和部分的關係,或者說是零件和模組的關係,若干零件合成乙個模組,而從本質上來說模組也可以是乙個零件;合成模式可以用來構造樹用來表示整體和部分的關係。合成模式將零件和組合而成的模組同等看待。

ruby設計模式之合成模式1 基本的合成模式

前幾天在 戲說設計模式 這篇文章中看到了一段關於組合模式的描述 composite mary今天過生日。我過生日,你要送我一件禮物。嗯,好吧,去商店,你自己挑。這件t恤挺漂亮,買,這條裙子好看,買,這個包也不錯,買。喂,買了三件了呀,我只答應送一件禮物的哦。什麼呀,t恤加裙子加包包,正好配成一套呀,...

RUBY設計模式之單例模式

單例singleton,是所有設計模式中最簡單的,但又是問題最多的。其實並不簡單,一定要慎用。singleton,和全域性變數很相似,所以要盡量的不用它,問題也就不會出來。而不是我們常常說的那樣這個我們可以用 singleton來實現。不出問題的唯一方法就是 別那麼做。如果要使用了,在使用之前必須知...

設計模式之合成復用原則

1.合成 聚合復用原則 盡量優先使用合成 聚合,盡量不要使用類繼承。盲目使用繼承會造成麻煩。所以在使用繼承時,一定要在是 is a 的關係時,再考慮使用。手機軟體顯然不是乙個,即不是 a,所以不能從手機品牌向下繼承。如下圖是不對的。聚合 表示一種弱的 擁有 關係,體現的是 a物件可以包含 b物件,但...