Java设计模式中装饰者模式应用详解

编程是一门艺术,大批量的改动显然是非常丑陋的做法,用心的琢磨写的代码让它变的更美观。

在现实生活中,常常需要对现有产品增加新的功能或美化其外观,如房子装修、相片加相框等,都是装饰器模式。

在软件开发过程中,有时想用一些现存的组件。这些组件可能只是完成了一些核心功能。但在不改变其结构的情况下,可以动态地扩展其功能。所有这些都可以釆用装饰器模式来实现。

1.装饰器模式(Decorator)的定义

装饰器模式:是指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。

2.装饰者设计模式的优点与不足

装饰者设计模式优点:

  • 装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用
  • 通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果
  • 装饰器模式完全遵守开闭原则

其主要缺点是:装饰器模式会增加许多子类,过度使用会增加程序得复杂性。

3.装饰器模式的实现思路

通常情况下,扩展一个类的功能会使用继承方式来实现。但继承具有静态特征,耦合度高,并且随着扩展功能的增多,子类会很膨胀。如果使用组合关系来创建一个包装对象(即装饰对象)来包裹真实对象,并在保持真实对象的类结构不变的前提下,为其提供额外的功能,这就是装饰器模式的目标。

4.装饰者代码示例

实例场景介绍:采摘水果,然后进行包装,这是主流程,然后需要对包装进行功能增强,比如:增加防伪标识、长途加固、标记加急。

/**
 * 包装接口
 */
public interface Bag {
    void pack();
}
/**
 * 这个是装饰者的基类
 */
public abstract class BagDecorator implements Bag {
    /**
     * 维持一个对 抽象构件对象的引用
     * 这个是想要增强的功能对象 将想要增强的功能对象传进来,然后才能进行功能增强
     */
    private Bag bag;
    /**
     * 注入一个抽象构件类型的对象
     * 将之前的对象传递进来,进行功能增强
     * @param bag
     */
    public BagDecorator(Bag bag) {
        this.bag = bag;
    }
    @Override
    public void pack() {
        bag.pack();
    }
}
/**
 * 增加防伪标识
 */
public class CheckedBagDecorator extends BagDecorator{
    public CheckedBagDecorator(Bag bag) {
        super(bag);
    }
    @Override
    public void pack() {
        super.pack();  
        checked();   
    }
    public void checked() {
        System.out.println("打印上防伪标识");
    }
}
/**
 * 加固增强
 */
public class ReinforceBagDecorator extends BagDecorator {
    public ReinforceBagDecorator(Bag bag) {
        super(bag);
    }
    public void pack() {
        super.pack();   
        reinforce();
    }
    public void reinforce() {
        System.out.println("加固了包装");
    }
}
/**
 * 加急功能增强
 */
public class SpeedDecorator extends BagDecorator {
    public SpeedDecorator(Bag bag) {
        super(bag);
    }
    @Override
    public void pack() {
        super.pack();
        speedy();
    }
    public void speedy() {
        System.out.println("打上加急标识");
    }
}
   public static void main(String[] args){
        AbstractFactory factory = new AppleFactory();
        /*得到水果*/
        Fruit fruit = factory.getFruit();
        fruit.draw();
        /*得到包装*/
        Bag bag = factory.getBag();
        /*下面是对包装进行装饰的过程(也就是功能增强的过程)*/
        /*现需要增加防伪标识*/
        bag = new CheckedBagDecorator(bag);
        /*加固功能*/
        bag = new ReinforceBagDecorator(bag);
        /*加急功能*/
        bag = new SpeedDecorator(bag);
        bag.pack();
    }

BagDecorator:功能增强基类,实现了待增强功能的行为接口,并持有一个包装接口成员变量,这个变量通过构造方法注入进来,这个成员变量就是上一个增强之后的结果,一定要在上一个增强的结果之上进行功能增强,否则,就将之前的功能丢失了,所以这个成员变量很关键。

还有就是每次进行包装pack的时候,一定要先调用super方法,先之前之前的包装,然后再进行增强。

5.装饰器模式的应用场景

装饰器模式通常在以下几种情况使用:

  • 当需要给一个现有类添加附加职责,而又不能采用生成子类的方法进行扩充时。例如,该类被隐藏或者该类是终极类或者采用继承方式会产生大量的子类。
  • 当需要通过对现有的一组基本功能进行排列组合而产生非常多的功能时,采用继承关系很难实现,而采用装饰器模式却很好实现。
  • 当对象的功能要求可以动态地添加,也可以再动态地撤销时。

装饰者设计模式,在Java中非常经典的例子是:

InputStream 的子类 FilterInputStream,OutputStream 的子类 FilterOutputStream,Reader 的子类 BufferedReader 以及 FilterReader,还有 Writer 的子类 BufferedWriter、FilterWriter 以及 PrintWriter 等,它们都是抽象装饰类。

到此这篇关于Java设计模式中装饰者模式应用详解的文章就介绍到这了,更多相关Java装饰者模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

你可能感兴趣的:(Java设计模式中装饰者模式应用详解)