装饰模式(Decorator)

1. 定义:装饰模式以对客户端透明的方式,动态地为一个对象(不是类)添加一些额外的功能。又名包装模式(Wrapper)

2. 装饰模式可以在不创造更多的子类的模式下,将对象的功能加以扩展。

3. 装饰模式与类继承的区别:

  • 装饰模式是一种动态行为,对已经存在的类进行随意组合,而继承是一种静态行为,一个类定义成什么样的,该类的对象便具有什么样的功能,无法动态改变;
  • 装饰模式扩展的是对象的功能,不需要增加类的数量,而类继承扩展的是的功能,通过对覆写父类方法或添加新方法完成;
  • 对于基类A,其已经有子类B,现在如果需要增加其它功能,则需要增加一个新的子类C,造成子类数量增多。装饰模式可以解决这一问题。

4. 装饰模式的基本实现示意图:

5. 装饰模式的角色:

  • 原始接口(Component):定义了一个接口方法;
  • 默认目标实现类(TargetComponent):对原始接口的默认实现方式,被认为是有待扩展的类,其方法operation被认为是有待扩展的方法;
  • 装饰类(Decorator):同样实现了原始接口,既可以是抽象类,也可以是具体实现类。其内部封装了一个原始接口的对象实例:targetComponent,这个实例往往被初始化成默认目标实现类实例。
  • 具体装饰实现类:继承自装饰类Decorator,其中可以扩展默认目标实现类对象的功能

6. 实例

下面看一个对开车功能扩展的实例(晚上+开车)

原始接口:

1 public interface Component {  
2     public void operation();  
3 }  

默认目标实现类:

1 public class TargetComponent implements Component {  
2     public TargetComponent(){}  
3     public void operation()  
4     {  
5            System.out.println("开车");  
6     }  
7 } 

装饰类:

public class Decorator implements Component {  
    private Component component;  //内部封装了原始接口的实例
    public Decorator(){}  
  
    public Decorator(Component component)  
    {  
           this.component = component;  
    }  
  
    public void operation() {  
           component.operation();  
    }  
} 

具体装饰类:

 1 public class ConcreteDecorator extends Decorator {  
 2   
 3     public ConcreteDecorator(){}  
 4   
 5     public ConcreteDecorator(Component component)  
 6     {  
 7            super(component);  
 8     }  
 9   
10     public void operation()  
11     {  
12          this.addedOperation();  //加入行为扩展
13          super.operation();  
14     }  
15    //扩展功能
16     public void addedOperation()  
17     {  
18            System.out.println("晚上");  
19     }  
20 } 

测试:

 1 /** 
 2  * 客户端类 
 3  * @author gjy 
 4  */  
 5   
 6 public class Client {  
 7        public static void main(String[] args) {  
 8               Component component = new TargetComponent();  
 9               Decorator decorator = new ConcreteDecorator(component);  
10               //客户端不变, 但已增加了责任  
11               decorator.operation();  
12                 
13        }  
14 }

输出结果:

晚上

开车

 

 

posted @ 2014-04-03 15:30  sky钦  阅读(88)  评论(0)    收藏  举报