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(把手)