何为装饰器模式

装饰器模式动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活,同时又不会改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

装饰设计模式可代替继承。

装饰模式类图

生活中的装饰器模式

1、一幅画有没有画框都可以挂在墙上,但是通常都是有画框的,并且实际上是画框被挂在墙上。在挂在墙上之前,画可以被蒙上玻璃,装到框子里;这时画、玻璃和画框形成了一个物体。

2、戏剧演员需要上台演戏,因此需要化妆,比如“化底色”、“拍腮红”、“涂胭脂”等等,演员还是那位演员,但其实只是画了一个妆变了样子。

3、在《Head First 设计模式》中,举例了咖啡的例子,咖啡中有“摩卡”、“豆奶”、“拿铁”、“奶泡”,每一份配料都有对应的加个,然后分别计算出来得出耐饿咖啡的总价格。

代码举例

接下来就以一幅画做为例子,首先需要一个接口。

interface Paint {
    void init();
}

实现该接口。

class TreePaint implements Plant {
    void init() {
        System.out.println("一棵油画树");
    }
}

需要一个抽象类,实现 Paint 接口

abstract class PaintDecorator implements Paint {
    protected Paint decoratedPaint;
 
   public PaintDecorator(Paint decoratedPaint){
      this.decoratedPaint = decoratedPaint;
   }
 
   public void init(){
      decoratedShape.init();
   }  
}

创建第一个具体的装饰类,给这幅画加上边框。

class BorderPaintDecorator extends PaintDecorator {
 
   public BorderPaintDecorator(Paint decoratedPaint) {
      super(decoratedPaint);     
   }
 
   @Override
   public void init() {
      decoratedPaint.init();         
      setBorder(decoratedShape);
   }
 
   private void setBorder(Paint decoratedPaint){
      System.out.println("木质边框");
   }
}

创建第二个具体的装饰类,在边框上加个绳子。

class SlingPaintDecorator extends PaintDecorator {

    public SlingPaintDecorator(Paint decoratorPaint) {
        super(decoratorPaint);
    }

    @Override
    public void init() {
        decoratorPaint.init();
        setBorder(decoratorPaint);
    }

    private void setBorder(Paint decoratedPaint){
        System.out.println(decoratedPaint + ":带吊绳");
    }
}

运行一下(装饰类可以被另一个装饰类给装饰)。

public class TestDecorator {

    public static void main(String[] args) throws Exception {
        TreePaint treePaint = new TreePaint();
        PaintDecorator paintDecorator = new BorderPaintDecorator(treePaint);
        paintDecorator = new SlingPaintDecorator(paintDecorator);
        paintDecorator.init();
    }
}

运行结果如下

一颗油画树
com.example.demo_springboot.decorator.TreePaint@4157f54e:木质边框
com.example.demo_springboot.decorator.BorderPaintDecorator@90f6bfd:带吊绳

Java 中的装饰器模式

Java 中出现装饰器模式主要是在 IO 包下,比如各种缓冲类 BufferReader 、BufferWriter 、 BufferInpuStream 、 BufferOutputStream 。