包装器模式

定义

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装

装饰器模式是对象结构动态修改方式,相较于继承关系,装饰器更加灵活,和代理模式相比,装饰器模式更偏重与对象本质行为或者属性的加强,比如窗口系统添加主题。而代理模式则更偏重于非本质行为的添加,比如文件系统中添加权限管理和修改日志。

实例

public interface Shape {
   void draw();
}
public class Circle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Shape: Circle");
   }
}
public class Rectangle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Shape: Rectangle");
   }
}
public class RedShapeDecorator extends ShapeDecorator {
 
   public RedShapeDecorator(Shape decoratedShape) {
      super(decoratedShape);     
   }
 
   @Override
   public void draw() {
      decoratedShape.draw();         
      setRedBorder(decoratedShape);
   }
 
   private void setRedBorder(Shape decoratedShape){
      System.out.println("Border Color: Red");
   }
}
public abstract class ShapeDecorator implements Shape {
   protected Shape decoratedShape;
 
   public ShapeDecorator(Shape decoratedShape){
      this.decoratedShape = decoratedShape;
   }
 
   public void draw(){
      decoratedShape.draw();
   }  
}

其类图关系为:


UML

上述是给Shape实例添加边框的实例,从功能角度出发,使用继承并重写draw方法就可以实现边框,只是有多少个需要边框的shape子类,就需要重写多少个类,这样类的数量很容易会爆炸,而采用包装器模式,保持该包装器职责单一,这里RedShapeDecorator类只负责添加红色边框(实际上不应该硬编码为红色),如果Circle类需要边框,也可以直接用RedShapeDecorator包装一下就行,而且多个包装器可以相互组合包装,能组合出复杂的功能。

总结

优点:

  • 装饰类和被装饰类是可以独立的,低耦合的。互相都不用知道对方的存在
  • 装饰模式是继承的一种替代方案,无论包装多少层,返回的对象都是is-a的关系(上面的例子:包装完还是Phone类型)。
  • 实现动态扩展,只要继承了装饰器就可以动态扩展想要的功能了。

缺点:

  • 多层装饰是比较复杂的,提高了系统的复杂度。不利于我们调试

在Java中,对类功能增强的方式三种:

  • 继承:重写或者修改类原有行为和属性
  • 代理模式:主要用于增加类非本质功能和属性,其本质上不是增强类原有功能,而是增加类非本质功能
  • 包装器模式: 主要用于增强类本质功能和属性,其本质是增强类原有能力

你可能感兴趣的:(包装器模式)