設計模式之裝飾模式

2022-03-21 08:52:53 字數 4536 閱讀 2283

裝飾模式(decorator):動態地給乙個物件新增一些額外的職責,就增加功能來說,裝飾模式比生成子類更為靈活。

上圖為裝飾模式的結構圖,component定義乙個物件介面可以給這些物件動態地新增職責。concretecomponent是定義了乙個具體的物件,也可以給這個物件新增一些職責(concretecomponent主要就是作為乙個具體的物件存在)。decorator,裝飾抽象類,繼承自component,從外類擴充套件component類的功能,相對於component來說無需知道decorator存在。concretedecorator就是具體的裝飾物件,起到給component新增職責的功能。

p.s:如果只有乙個concretecomponent而沒有抽象的component類,那麼decorator類可以是concretecomponent的乙個子類。同樣道理,如果只有乙個concretedector類(即只有乙個具體的裝飾類),那麼就沒必要單獨建立乙個decorator類,可以把decorator和concretedecorator的職責合併。

從上圖中可以看到裝飾模式的四要素:

1.裝飾的介面即component;

2.裝飾的具體物件concretecomponent,用於實現新增職責的功能;

3.抽象的裝飾類,同時繼承自component;

4.具體的裝飾類,繼承自抽象的裝飾類。

component:

abstract

class

component

concretecomponent:

class

concretecomponent:component

}

decorator抽象裝飾類:

abstract

class

decorator : component

//////

設定component

/// ///

public

void

setcomponent(component component)

//////

重寫operation方法,實際執行的是component的operation

/// public

override

void

operation()}}

具體裝飾類:

class

concretedecoratora:decorator

}class

concretedecoratorb : decorator

}class

concretedecoratorc : decorator

}

呼叫方法:

concretecomponent component = new

concretecomponent();

concretedecoratora c1 = new

concretedecoratora();

concretedecoratorb c2 = new

concretedecoratorb();

c1.setcomponent(component);

c2.setcomponent(c1);

c2.operation();

呼叫效果如下:

裝飾的過程:先定義了具體的component類concretecomponent,然後使用concretedecoratora 的例項化物件c1來包裝component,然後用concretedecoratorb的物件c1來包裝c1,最終執行c2的operation方法。其實裝飾模式最主要的是使用setcomponent來對物件進行包裝的。這樣每個裝飾物件的例項就和如何使用這個物件分離開了,每個裝飾物件只關心如何被新增到物件鏈當中。

整個過程是層層傳遞的,最終會先執行被傳遞的那個component物件(也可以說是具體的裝飾物件),整個的過程主要通過setcomponent進行完成,以及在具體物件的operation中執行base的操作(這樣才可以執行到傳遞的component的行為,其實就是乙個繼承的作用)。

下面舉例乙個穿衣服的裝飾模式例子:

場景:衣服有很多種,t恤,褲子,西裝,運動鞋,皮鞋,領帶等,至於怎麼組合無需關心,交給客戶決定。

分析:衣服要有人來穿,所以人是乙個具體的component,上述的各種衣服最終還是乙個衣服,所以乙個衣服的積累,作為抽象的裝飾存在,另外各種衣服就是乙個個具體的裝飾物件。

人(person具體的component):

class

person

//當前人

private

string

name;

public person(string

name)

//////

展示衣服

/// public

virtual

void

show()

", name));}}

衣服(服飾的基類):

///

///衣服類

/// class

finery:person

public

override

void

show()}}

其他具體的服飾類:

///

///t恤

/// class

tshirt:finery

}//////

褲子

/// class

trouser:finery

}//////

運動鞋

/// class

sportshoes:finery

}//////

西裝

/// class

suit:finery

}//////

皮鞋

/// class

eathershoes:finery

}//////

領帶

/// class

tie:finery

}

呼叫:

console.writeline("

第一種打扮:");

person person = new person("

blue");

tshirt shirt = new

tshirt();

trouser trouser = new

trouser();

sportshoes sportshoes = new

sportshoes();

//開始裝飾了

shirt.decorate(person);

trouser.decorate(shirt);

sportshoes.decorate(trouser);

//開始展示衣服了

sportshoes.show();

console.writeline();

console.writeline(

"第二種打扮:");

suit suit = new

suit();

eathershoes eathershoes = new

eathershoes();

tie tie = new

tie();

//再次裝飾了

suit.decorate(person);

eathershoes.decorate(suit);

tie.decorate(eathershoes);

//開始展示衣服了

tie.show();

**中一共展示了兩種不同的裝扮,除了例項化的衣服不同之外,其餘過程均相同。例項化乙個person類,即例項化乙個具體的component,然後開始例項化各種各樣的衣服,然後通過decorate方法進行裝飾,最後呼叫show進行衣服的展示,效果如下:

現在如果想增加一種衣服怎麼做呢,很簡單,增加乙個衣服類,繼承自finery類,重寫show方法即可。如果要換裝扮,也很簡單,只需定義需要的衣服型別,並且進行裝飾即可完成,**是不是非常的低耦合呢。

後記總結:

裝飾模式是為已有功能動態地新增更多功能的一種方式。當系統需要新功能時,裝飾模式提供了乙個很好的方案,它把每個要裝飾的功能放在了單獨的類中,並讓這個類包裝它所需要的物件,因此當需要執行特殊行為時,客戶**就可以在執行時有選擇地使用裝飾功能包裝物件。

優點:把類的核心職責和裝飾功能區分開了,而且去除相關類中重複的裝飾邏輯。

設計模式之裝飾設計模式

1.目的 動態擴充套件類的行為 開閉原則 對擴充套件開放,對修改關閉 2.要點 裝飾類和被裝飾類都實現同乙個介面或者繼承同乙個類 3.具體實現 被裝飾元件介面 被裝飾元件實現類實現 抽象類構建被裝飾元件實現被裝飾元件介面 裝飾類繼承抽象類 裝飾類 重寫抽象類方法 裝飾 4.例項 被裝飾類介面 pub...

設計模式之裝飾模式

有時如果需要對某乙個類增加乙個功能,可以使用繼承來實現。但是如果想要只是對某乙個物件來增加一項功能,則可能會用到裝飾模式。裝飾模式的主要作用是動態的給某乙個物件新增某些功能。如果此時使用繼承來新增功能時,會產生大量的子類,導致難以維護。裝飾模式的簡要類圖如下 其中 component為待增加功能 即...

設計模式之裝飾模式

template pattern 即模板模式 核心思想 產品不變的部分首先實現,將易變的部分抽象出來供子類完成。例如 一雙運動鞋大體製作流程各廠家基本一致,但是各環節實現細節可有些不一樣,不一樣的部分抽象出來讓不同廠家實現。即先有個框架,細節交給不同廠家實現 程式設計例項 趙本山小品中提到的將大象裝...