Andy Back-end Dev Engineer

设计模式-装饰者模式


装饰者设计模式

之前在过滤器Filter一文中写到过装饰者设计模式,现在重新总结一下这中常用的设计模式。

装饰者设计模式时为了能够在不修改目标类也不适用继承的情况下,动态地扩展一个类的功能。它是通过创建一个包装对象,也就是装饰者来达到增强目标类的目的的。

装饰者设计模式的实现有两个要求:

  1. 装饰者类与目标类要实现相同的接口,或继承自相同的抽象类。
  2. 装饰者类中要有目标类的引用作为成员变量,而具体的赋值一般通过带参构造器完成。

在装饰者设计模式中,装饰者类一般是不对目标类进行增强的。装饰者类作为一个基类,具体的装饰者继承自这个基类,对目标类进行具体的、单功能的增强。这样做的好处是,在很方便的情况下可以实现多重地、组合式地增强。

代码实现:

  1. 定义业务接口ISomeService
    // 业务接口
    public interface ISomeService {
     String doSome();
    }
    
  2. 定义目标类 SomeServiceImpl
    // 目标类
    public class ISomeServiceImp implements ISomeService {
    
     @Override
     public String doSome() {
         return "   abc   ";
     }
    }
    
  3. 定义装饰者基类 SomeServiceWrapper
    // 定义装饰者基类
    // 要求1. 要有无参构造器
    // 要求2. 不对目标类的目标方法进行增强
    public class SomeServiceWrapper implements ISomeService{
     // 声明装饰类要装饰的目标对象
     private ISomeService target;
    	
     public SomeServiceWrapper() {
         super();
     }
    	
     // 目标对象通过带参构造器传入
     public SomeServiceWrapper(ISomeService target) {
         super();
         this.target = target;
     }
    
     // 调用目标类的目标方法,但不对其进行增强
     @Override
     public String doSome() {
         return target.doSome();
     }
    }
    
  4. 定义去空格装饰者类 TrimDecorator
    public class TrimDecorator extends SomeServiceWrapper{
    
     public TrimDecorator() {
         super();
     }
    
     public TrimDecorator(ISomeService target) {
         super(target);
     }
    
     @Override
     public String doSome() {
         // 对目标方法进行增强
         return super.doSome().trim();
     }
    }
    
  5. 定义小写变大写装饰者类 ToUpperCaseDecorator
    public class ToUpperCaseDecorator extends SomeServiceWrapper{
    
     public ToUpperCaseDecorator() {
         super();
     }
    
     public ToUpperCaseDecorator(ISomeService target) {
         super(target);
     }
    
     @Override
     public String doSome() {
         // 增强目标方法
         return super.doSome().toUpperCase();
     }
    }
    
  6. 定义测试类
    public class MyTest {
     public static void main(String[] args) {
         // 创建原始的目标对象
         ISomeService target = new ISomeServiceImp();
         System.out.println("装饰前的输出: " + target.doSome());
    		
         // 进行去空格增强
         ISomeService trimService = new TrimDecorator(target);
         System.out.println("第一次增强结果: " + trimService.doSome());
    		
         // 进行去空格增强
         ISomeService toUpperCaseService = new ToUpperCaseDecorator(trimService);
         System.out.println("第二次增强结果: " + toUpperCaseService.doSome());
     }
    }
    

装饰者设计模式与静态代理设计模式的对比

相同点

  1. 装饰者类与目标类要求实现同一接口;静态代理类与目标类要求也实现同一接口。
  2. 装饰者类与静态代理类都可以实现增强目标类的功能。
  3. 装饰者类与静态代理类中都具有目标类的引用,目的都是为了在其中调用目标类的方 法。

不同点

  1. 装饰者设计模式就是为了增强目标类;静态代理设计模式是为了保护和隐藏目标对象,让客户类只能访问代理对象,而不能直接访问目标对象。
  2. 装饰者类中的目标类的引用是通过带参构造器传入的;静态代理类中的目标类的引用,一般都是在代理类中直接创建的,目的就是为了隐藏目标对象。
  3. 装饰者基类一般不对目标对象进行增强,而是由不同的具体装饰者进行增强的,且这些具体的装饰者可以形成增强链,对目标对象进行连续增强。静态代理类会直接对目标对象进行增强,需要哪些增强的功能,一次性在静态代理类中完成,没有增强链的概念。

上一篇 常用工具-git

Comments

Content