(六)装饰者模式

一、概念

装饰者模式就是对现有类的功能进行扩展,相比继承更加灵活一些。

二、例子

            装饰器模式的 UML 图

图中ShapeDecorator为装饰者抽象类,里面有成员shape(也可以写到RedShapeDecorator中,图中在ShapeDecorator和RedShapeDecorator中仅有一处存在shape即可,图中两处均有,个人觉得有误)、接口的函数draw、以及构造函数来对成员Shape进行赋值。RedShapeDecorator通过继承抽象装饰类来对Shape子类的功能进行扩展,重写了draw,以及在自己的构造函数中调用对Shape进行功能扩展的函数setRedBorder()函数。

具体代码如下:

//基类接口
public interface Shape {
   void draw();
}

//子类
public class Rectangle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Shape: Rectangle");
   }
}
public class Circle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Shape: Circle");
   }
}

//抽象装饰类
public abstract class ShapeDecorator implements Shape {
   protected Shape decoratedShape;
 
   public ShapeDecorator(Shape decoratedShape){
      this.decoratedShape = decoratedShape;
   }
 
   public void draw(){
      decoratedShape.draw();
   }  
}

//使用装饰类对Shape子类的功能进行扩展
public class RedShapeDecorator extends ShapeDecorator {
 
   public RedShapeDecorator(Shape decoratedShape) {
      ShapeDecorator(decoratedShape);     
   }
 
   @Override
   public void draw() {
      decoratedShape.draw();         
      setRedBorder(decoratedShape);
   }
 
   private void setRedBorder(Shape decoratedShape){
      System.out.println("Border Color: Red");
   }
}

//测试类
public class DecoratorPatternDemo {
   public static void main(String[] args) {
 
      Shape circle = new Circle();
      ShapeDecorator redCircle = new RedShapeDecorator(new Circle());
      ShapeDecorator redRectangle = new RedShapeDecorator(new Rectangle());
    
      System.out.println("Circle with normal border");
      circle.draw();
 
      System.out.println("\nCircle of red border");
      redCircle.draw();
 
      System.out.println("\nRectangle of red border");
      redRectangle.draw();
   }
}

三、优缺点

优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

缺点:多层装饰比较复杂。

四、个人理解

装饰者模式有点类似于上一节的适配器模式的扩展。适配器模式中有成员B,并通过继承实现A的函数,在A的函数中调用B的函数。而抽象装饰类是有成员A且继承了类A,为了能扩展各式各样的功能,用了一个类C继承抽象装饰类,在C中,实现了类A的虚函数,且在虚函数中调用了成员A的虚函数并调用了C中写的针对类A扩展的功能函数。其中的成员均是通过构造函数传入类对象进行赋值(装饰者模式类C的构造函数调用了抽象装饰类的构造函数对成员A进行赋值)。

这样看装饰者模式有点类似于适配器模式的一个变形或者特例。

你可能感兴趣的:(设计模式)