設計模式 組合模式

2021-07-22 04:19:31 字數 3122 閱讀 3512

組合模式

什麼是組合模式?組合模式是將一組物件組合為可像單個物件一樣被使用的結構。同樣地,舉個栗子來說明。

假設現在某國突然想教訓一下不斷念想某魚島的某本,於是開始招賢納士,招兵買馬。打戰吧,肯定要有士兵,士兵肯定有攻擊力,而且不同兵種攻擊力肯定不同。假設現在我們有乙個soldier抽象類,類的定義如下:

有兩個兵種,乙個是步兵infantryman,乙個是炮兵artilleryman,返回值的大小表示攻擊力的大小,定義如下:

有了這兩個基本兵種,我們就可以開始組建軍隊了。首先,這個軍隊即可以包含自己招募來的炮兵或者步兵,也可以包含從別的軍隊抽調過來的部隊,於是分別設計了兩個物件陣列來分別儲存士兵物件和軍隊物件,同時也提供了新增士兵物件和軍隊物件的方法,還有移除物件的方法(沒有寫出),軍隊總戰鬥力就是所有作戰單位的攻擊力的總和,所以只需要遍歷這些作戰單位物件並把攻擊力數值進行疊加即可。具體**如下:

由於某本是個島國,我們會需要運兵船輸送兵力,此刻可以新建乙個troopcarrier類,類中可以包含特定數目的步兵或者炮兵,寫法和army類差不多。通常我們稱army物件和troopcarrier物件為組合物件,稱infantryman物件和artilleryman物件為區域性物件。可以看出組合物件中需要包含新增和刪除子物件的方法,而區域性物件不用,但兩者共同需要實現的操作是aggressivity(共同的操作集)。

現在我們知道了,我們的火力輸出形式主要有單體士兵輸出和整個軍隊單位的輸出,在這裡為了統一,我們把前文的抽象類soldier改為unit,意指作戰單位。

一般的組合模式會在抽象類中新增add和remove方法,所以現在我們的抽象基類為:

可是問題又來了,為了確保介面的統一,組合類和區域性類都繼承了這個抽象基類,但是事實上區域性類並不需要實現這個方法,明擺著嘛,軍隊可以新增成員,士兵就不可以了,除非懷孕了。。。。所以在不小心呼叫了士兵單位的add和remove方法的時候,應該丟擲乙個異常來提示我們。這時候我們只需要在抽象基類中新增預設實現就行了(具體**省略)。

下面是改寫後的army類:

class army extends unit

array_push($this->unit, $unit);

}function removeunit(unit $unit)

}$this->unit=$temp;

}function aggressivity()

return $res;}}

如果現在我們又需要新的兵種如傘兵,然後同時需要新增乙個空降部隊,需要怎麼做?對的,很簡單,我們只需要再新增乙個傘兵區域性類和空降部隊組合類即可,無需大範圍修改原來的**。讓我們從客戶端**角度來感受一下。

//某國戰隊

$chinese_army=new army();

//傘兵物件

$s1=new infantryman();

//炮兵物件

$s2=new artilleryman();

//傘兵物件

$s3=new paraboy();

//增加一艘運兵船

$troopcarrier1=new troopcarrier();

$troopcarrier1->addunit($s1);

//增加空降部隊

$air=new paratroops();

$air->addunit($s3);

//將運兵船和空降部隊新增到中國戰隊

$chinese_army->addunit($troopcarrier1);

$chinese_army->addunit($air);

當我們需要得知某國戰隊的戰鬥力時,只需要簡單地呼叫$chinese_army->aggressivity()便可將複雜的操作隱藏。

看完了組合模式的**,也許有人有疑問了,既然區域性類不需要addunit和removeunit方法,為什麼我們還要新增呢?這樣做不是顯得很冗餘嗎?

為了解決這個問題,我們很自然就會想到需要對這兩種不同的物件進行區分,組合類就應當實現addunit和removeunit方法,而區域性類就不需要去實現。為此,我們將這兩個操作子物件的方法降到下一級物件中,將組合類放在compositeunit抽象類下。

//unit抽象基類

abstract class unit

//共同操作集

abstract function aggressivity();

}//compositeunit抽象類,將組合類的特徵抽象出來

abstract class compositeunit extends unit

//獲取作戰單位列表

protected function units()

//新增作戰單位

function addunit(unit $unit)

array_push($this->unit, $unit);

}//移除作戰單位

function removeunit(unit $unit)

}$this->unit=$temp;}}

組合類army:

所以,現在,當我們需要新增物件的時候,首先需要呼叫getcomposite()方法判斷物件是組合物件還是區域性物件。

組合模式的問題:

1.當特殊的物件越來越多,組合模式開始 顯得弊大於利,因為需要在每個特殊物件類中對特殊條件進行判斷而無法自動化來強制執行規則,所以在大部分區域性物件可互換的情況下,組合模式才最適用。

2.當物件樹中有大量的子army物件,乙個簡單的呼叫可能會導致系統崩潰,為了降低組合操作的成本,可以在父級物件中緩衝計算結果,使接下來的呼叫減少系統開銷。

3.組合模式使資料儲存在關係型資料庫中並不輕鬆,但卻非常適合持久化xml。

組合模式 設計模式 組合模式

1.需求分析 假設要給乙個大公司做辦公管理系統,公司有人力資源部 財務部等,然後公司在其他城市還有分公司,分公司也有自己的人力資源部 財務部等,要求總公司 分公司以及各部分成樹狀結構管理。要完成這麼乙個系統,為了有乙個更好的設計,方便開發的展開,就需要了解乙個設計模式 組合模式。2.定義 將物件組合...

設計模式 組合模式 組合模式使用

目錄 組合模式概括 組合模式使用場景 定義 將物件組合成樹形結構以表示 部分 整體 的層次結構 作用 使客戶端對單個物件和組合物件保持一致的處理方式 使用場景 1.希望客戶端可以忽略組合物件與單個物件的差異時 2.處理乙個樹形結構時 優點 清楚的定義分層次的複雜物件,表示物件的全部或部分層次 讓客戶...

設計模式 組合設計模式

組合模式 composite pattern 又稱部分整體模式,用於把一組相似的物件當做乙個單一的物件,組合模式依據樹形來組合物件,用來表示部分以及整體層次,為結構型設計模式,它建立來物件組的樹形結構。意圖 將物件組合成樹形結構以表示 部分 整體 的結構層次,組合模式使得使用者對單個物件和組合物件的...