装饰模式(Decorator)

装饰(Decorator)模式又称包装(Wrapper)模式。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。

装饰(Decorator)模式又称包装(Wrapper)模式。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。

我们通过日常使用的手机换代来解释什么是装饰模式。手机总体来看存在三个大的版本,分别是"黑白屏时代"、"半智能时代(即NOKIA的天下)"和"只能手机(即Android、IOS)",如下图:

装饰模式(Decorator)

上图中,手机的黑白屏就是装饰模式的基础构建,其他代的手机都是在黑白屏手机基础上进行增强的。如下:

  • 在黑屏手机时代,手机只能发短信和打电话;

  • 在半智能手机时代,手机不仅可以发短信、打电话,而且可以浏览网页,通过WAP;

  • 在智能手机时代,手机除了上面的功能外,可以完全当作一个PC电脑。功能非常丰富;

如果将上面的手机实例使用Java进行描述,UML类图如下:

装饰模式(Decorator)

上图中,NoopsychePhone和HalfNoopsychePhone均是在BlackAndWhitePhone基础上进行扩展加强功能。其中:

  • Phone:定义手机的基础功能接口,在Java中使用接口或者抽象类担任。

  • BlackAndWhitePhone:黑白屏手机实现

  • Decorator:手机功能扩展的基础类,所有扩展新功能的手机均需要继承该类,该类同时需要引用一个Phone对象。

  • HalfNoopsychePhone:半智能手机实现

  • NoopsychePhone:智能手机实现

装饰模式的结构

装饰模式使用原来被装饰的类的一个子类的实例,把客户端的调用委派到被装饰类。装饰模式的关键在于这种扩展是完全透明的。类图如下:

装饰模式(Decorator)

在装饰模式中的各个角色有:

  • 抽象构件(Component)角色:规范准备接收附加责任的对象。在Java中使用接口担任;

  • 具体构建(Concrete Component)角色:将要接收附加责任的类;

  • 装饰(Decorator)角色:持有一个构建(Component)对象的实例,并定义一个与抽象构件接口一致的接口;

  • 具体装饰(Concrete Decorator)角色:负责给构件对象"贴上"附加功能;

 

Java代码:

// 抽象构件角色
public interface Component {
    public void sampleOperation();
}
 
// 具体构件角色,将要接收附加功能的基础类
public class ConcreteComponent implements Component {
    public void sampleOperation() {
        System.out.println(this.getClass().getName() + " sampleOperation()");
    }
}
 
// 装饰角色,该类提供了与抽象构件(待装饰类)一样的接口
public class Decorator implements Component {
    private Component component;
 
    public Decorator(Component component) {
        this.component = component;
    }
 
    public Decorator() {}
 
    public void sampleOperation() {
        component.sampleOperation();
    }
}
 
// 具体装饰角色(提供一个目标构件没有的功能,或者增强原有的功能)
public class ConcreteDecorator extends Decorator {
    private static final String NAME = ConcreteDecorator.class.getName();
 
    public ConcreteDecorator() {}
 
    public ConcreteDecorator(Component component) {
        super(component);
    }
 
    @Override
    public void sampleOperation() {
        System.out.println("[*] " + NAME + " => 开始包装");
        super.sampleOperation();
        System.out.println("[*] " + NAME + " => 包装结束");
    }
}
 
// 客户端
public class Client {
    public static void main(String[] args) {
        Decorator decorator = new ConcreteDecorator(new ConcreteComponent());
        decorator.sampleOperation();
    }
}

 

模式在Java中的应用

装饰模式在Java IO中得到了淋漓精致的使用。Java中的IO框架使用了装饰模式,下面我们以输入流InputStream为例。类图如下:

装饰模式(Decorator)

上图中是Java IO中输入流InputStream的部分类图,详解如下:

  • InputStream 接口定义了装饰模式抽象构建的接口列表;

  • FileInputStream 类是装饰模式的具体构建;

  • FilterInputStream 类是装饰模式装饰角色的具体实现,其他具体装饰角色均继承自该角色;

  • BufferedInputStream 类是具体装饰角色的具体实现,提供用来了使用缓存读取文件的接口;

  • DataInputStream 类是具体装饰角色的具体实现,提供获取int、float、double等基础数据的接口;

最大的骄傲于最大的自卑都表示心灵的最软弱无力。——斯宾诺莎
0 不喜欢
说说我的看法 -
全部评论(
没有评论
关于
本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,请来信告知:hxstrive@outlook.com
公众号