?

GoF 動態地給一個對象添加一些額外的職責。就增加功能來說,Decorator(裝飾)模式相比生成子類更為靈活。

在系統開發的過程中,我們希望給某個對象而不是整個類添加一些功能。例如:我們要做一扇門,現在為了能將門做的美觀和安全需要給門加上鎖和把手,還可能給門加上窗戶和雕花。這里我們把這些要添加的東西叫做門的屬性。

使用繼承機制是添加功能的一種有效途徑,從其他類繼承過來的屬性可以被多個子類的實例所使用。但這種方式不夠靈活,因為如果我們的門做工過細價錢也就高,有些顧客可能不需要這樣的門。這樣我們就需要靈活添加門的屬性。

一種較為靈活的方式是使用Decorator模式。Decorator模式的效果是:讓我們可以創建以decorator對象—負責新的功能的對象—開始的一條對象“鏈”,并結束于最初的對象。

Decorator 模式幫助我們將問題分解為兩個部分:

l??????? 如何實現提供新功能的對象。

l??????? 如何為每種特定情況將對象組織起來。

一個實際的例子是JavaI/O類就廣泛使用了Decorator模式,大家有興趣可以去研究一下。直到現在我還沒有研究過。

?

裝飾模式包括如下角色:

l??????? 抽象構件(Component):給出一個抽象接口,以規范準備接收附加責任的對象。

l??????? 具體構件(Concrete Component):定義一個將要接收附加責任的類。

l??????? 裝飾(Decorator):持有一個構件對象的實例,并定義一個與抽象構件接口一致的接口。

l??????? 具體裝飾(Concrete Decorator):負責給構件對象貼上附加的責任。

下面是Decorator模式的UML圖:

下面是事例代碼:

?1 package ?Decorator;
?2
?3 ?
?4
?5 /*
?6
?7 ?*?定義一個抽象類派生出一個具體門(Door)和一個裝飾抽象類(Decorator)
?8
?9 ? */

10
11 public ? abstract ? class ?Component
12
13 {
14
15 ??????? public ? abstract ? void ?sampleOperation();
16
17 }
// end?abstract?class?Component
18
19 ?
20
21

package Decorator;

?

/*

?* 具體的一個門

?*/

public class Door extends Component

{

?????? public void sampleOperation()

?????? {

????????????? System.out.println("Build a door!");

?????? }//end sampleOperation()

?

}//end class Door

?

?1 package ?Decorator;
?2
?3 ?
?4
?5 /*
?6
?7 ?*?一個裝飾抽象類,下面派生出一個用來裝飾門的鎖子和一個把手
?8
?9 ? */

10
11 public ? abstract ? class ?Decorator? extends ?Component
12
13 {
14
15 ??????? private ?Component?component;
16
17 ???????
18
19 ??????? public ??Decorator(Component?component)
20
21 ??????? {
22
23 ?????????????? this .component? = ?component;
24
25 ???????}
// end?Decorator
26
27 ???????
28
29 ??????? public ? void ?sampleOperation()
30
31 ??????? {
32
33 ?????????????? this .component.sampleOperation();
34
35 ???????}
// end?sampleOperation()
36
37 ???????
38
39 }
// end?abctract?class?Decorator
40
41

?

package Decorator;

?

/*

?* 用來裝飾門的把手

?*/

public class Knob extends Decorator

{

?????? public Knob(Component component)

?????? {

????????????? super(component);

?????? }//end ConcreteDecorator2(...)

?

??? public void sampleOperation()

??? {

???????? super.sampleOperation ();

???????? System.out.println("Add an Knob( 把手 )");

??? }//end sampleOperation()

?

}//END CLASS Knob

?

package Decorator;

?

/*

?* 用來裝飾門的門鎖

?*/

public class Lock extends Decorator

{

?????? public Lock(Component component)

?????? {

????????????? super(component);

?????? }//end ConcreteDecorator1(...)

?

?????? public void sampleOperation()

?????? {

????????????? super.sampleOperation ();

????????????? System.out.println("Add a lock( )");

?????? }//end sampleOperation()

?

}//end class Lock

?

?1 package ?Decorator;
?2
?3 ?
?4
?5 public ? class ?DecoratorPattern
?6
?7 {
?8
?9 ??????? private ?Component?door? = ? new ?Door(); // 創建一個扇門(向下轉型)
10
11 ???????
12
13 ??????? private ?Component?lock? = ? new ?Lock(door); // 添加一把鎖(向下轉型)
14
15 ??????? private ?Component?knob? = ? new ?Knob(lock); // 再添加一個把手(向下轉型)
16
17 ???????
18
19 ??????? public ? void ?showDecorator()
20
21 ??????? {
22
23 // ????????????door.sampleOperation();
24
25 // ????????????lock.sampleOperation();
26
27 ??????????????knob.sampleOperation();
28
29 ???????}
// end?showDecorator()
30
31 ???????
32
33 ??????? public ? static ? void ?main(String[]?args)
34
35 ??????? {
36
37 ??????????????System.out.println( " Decorator?Pattern!\n " );?????????
38
39 ??????????????DecoratorPattern?dp? = ? new ?DecoratorPattern();
40
41 ??????????????dp.showDecorator();
42
43 ???????}
// end?main()
44
45 ???
46
47 }
// end?class?DecoratorPattern
48
49

下面是執行結果:

Decorator Pattern!

?

Build a door!

Add a lock( )
Add an Knob(把手)