《設計模式精解》學習筆記(十一)------Decorator(裝飾)模式
GoF:動態地給一個對象添加一些額外的職責。就增加功能來說,Decorator(裝飾)模式相比產生子類更為靈活。
在系統開發的過程中,我們希望給某個對象而不是整個類添加一些功能。例如:我們要做一扇門,現在為了能將門做的美觀和安全需要給門加上鎖和把手,還可能給門加上窗戶和雕花。這裡我們把這些要添加的東西叫做門的屬性。
使用繼承機制是添加功能的一種有效途徑,從其他類繼承過來的屬性可以被多個子類的執行個體所使用。但這種方式不夠靈活,因為如果我們的門做工過細價錢也就高,有些顧客可能不需要這樣的門。這樣我們就需要靈活添加門的屬性。
一種較為靈活的方式是使用Decorator模式。Decorator模式的效果是:讓我們可以建立以decorator對象—負責新的功能的對象—開始的一條對象“鏈”,並結束於最初的對象。
Decorator模式協助我們將問題分解為兩個部分:
l 如何?提供新功能的對象。
l 如何為每種特定情況將對象組織起來。
一個實際的例子是Java的I/O類就廣泛使用了Decorator模式,大家有興趣可以去研究一下。直到現在我還沒有研究過。
裝飾模式包括如下角色:
l 抽象構件(Component):給出一個抽象介面,以規範準備接收附加責任的對象。
l 具體構件(Concrete Component):定義一個將要接收附加責任的類。
l 裝飾(Decorator):持有一個構件對象的執行個體,並定義一個與抽象構件介面一致的介面。
l 具體裝飾(Concrete Decorator):負責給構件對象“貼上”附加的責任。
下面是Decorator模式的UML圖:
下面是案例代碼:
package Decorator;
/*
* 定義一個抽象類別派生出一個具體門(Door)和一個裝飾抽象類別(Decorator)
*/
public abstract class Component
{
public abstract void sampleOperation();
}//end abstract class Component
package Decorator;
/*
* 具體的一個門
*/
public class Door extends Component
{
public void sampleOperation()
{
System.out.println("Build a door!");
}//end sampleOperation()
}//end class Door
package Decorator;
/*
* 一個裝飾抽象類別,下面派生出一個用來裝飾門的鎖子和一個把手
*/
public abstract class Decorator extends Component
{
private Component component;
public Decorator(Component component)
{
this.component = component;
}//end Decorator
public void sampleOperation()
{
this.component.sampleOperation();
}//end sampleOperation()
}//end abctract class Decorator
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
package Decorator;
public class DecoratorPattern
{
private Component door = new Door();//建立一個扇門(向下轉型)
private Component lock = new Lock(door);//添加一把鎖(向下轉型)
private Component knob = new Knob(lock);//再添加一個把手(向下轉型)
public void showDecorator()
{
// door.sampleOperation();
// lock.sampleOperation();
knob.sampleOperation();
}//end showDecorator()
public static void main(String[] args)
{
System.out.println("Decorator Pattern!/n");
DecoratorPattern dp = new DecoratorPattern();
dp.showDecorator();
}//end main(...)