Java设计模式-装饰者模式

首先简单介绍一下装饰者模式是个什么样的结构?
装饰者模式的结构设计很巧妙,可以动态添加对象功能。它遵循“合成/聚合复用原则”,这个原则的思想是代码复用应该尽可能使用委托,而不是继承。因为继承是一种紧密耦合,任何父类的改动都会影响其子类,不利于系统维护。而委托则是松散耦合,只要接口不变,委托类的改动并不会影响其上层对象。
装饰者模式就是充分运用了这种思想,通过委托机制,复用系统中的各个组件,在运行时,可以将这些功能组件进行叠加,从而构造一个“超级对象”,使其拥有所有这些组件的功能。而各个子功能模块,被很好地维护在各个组件的相关类中,层级结构整洁易于维护,这样可以很好地将功能组件和核心组件进行分离,彼此互不影响,并在需要的时候,有机地结合起来。

接下来我使用案例分析一下装饰者模式

  • 首先看一下装饰者模式的结构图:
    案例结构图
    从图中可以看出,装饰者(Decorator)和被装饰者(ConcreteComponent)拥有相同的接口Component。被装饰者通常是系统的核心组件,实现特定的功能目标。而装饰者则可以在被装饰者的方法前后,加上特定的前置处理和后置处理,增强被装饰者的功能。
  • 装饰器接口:
/**
 * @Summary 装饰者模式-Component
 * @Description 声明装饰接口
 * @Author helon
 * @Date 2018/11/18 4:24 PM
 * @Param 
 * @return 
 **/
public interface IPacketCreator {
    /**
     * @Summary  核心组件处理内容的抽象方法
     * @Description TOD
     * @Author helon
     * @Date 2018/11/18 4:23 PM
     * @Param []
     * @return java.lang.String
     **/
    String handleContent();
}
  • 核心组件实现类(被装饰者):
/**
 * @className: PacketCoreCreator
 * @summary: 装饰者模式-ConcreteComponent
 * @Description: 具体的组件,它的功能是构造要处理的核心内容
 * @author: helon
 * date: 2018/11/18 4:30 PM
 * version: v1.0
 */
public class PacketCoreCreator implements IPacketCreator {
    /**
     * @Summary 核心组件
     * @Description 具体处理逻辑实现
     * @Author helon
     * @Date 2018/11/18 4:34 PM
     * @Param []
     * @return java.lang.String
     **/
    @Override
    public String handleContent() {

        return "deal core content\n";
    }
}
  • 装饰者抽象类:
/**
 * @className: PacketDecorator
 * @summary: 装饰者模式-装饰者Decorator
 * @Description: 装饰者抽象类
 * @author: helon
 * date: 2018/11/18 4:39 PM
 * version: v1.0
 */
public abstract class PacketDecorator implements IPacketCreator {
    IPacketCreator component;
    public PacketDecorator(IPacketCreator component) {
        this.component = component;
    }
}
  • 装饰者具体实现类(用户相关操作):
/**
 * @className: PacketUserDecorator
 * @summary: 具体实现用户相关操作的装饰器
 * @Description: TODO
 * @author: helon
 * date: 2018/11/18 4:45 PM
 * version: v1.0
 */
public class PacketUserDecorator extends PacketDecorator {
    public PacketUserDecorator(IPacketCreator c) {
        super(c);
    }
    @Override
    public String handleContent() {
        StringBuilder sb = new StringBuilder();
        sb.append("deal user content begin\n");
        //核心组件处理逻辑
        sb.append(component.handleContent());
        sb.append("deal user content end\n");
        return sb.toString();
    }
}
  • 装饰者具体实现类(日期相关操作):
/**
 * @className: PacketDateDecorator
 * @summary: 具体实现时间相关操作的装饰器
 * @Description: TODO
 * @author: helon
 * date: 2018/11/18 5:00 PM
 * version: v1.0
 */
public class PacketDateDecorator extends PacketDecorator {
    public PacketDateDecorator(IPacketCreator c) {
        super(c);
    }
    @Override
    public String handleContent() {
        StringBuilder sb = new StringBuilder();
        sb.append("deal date:" + System.currentTimeMillis() + "\n");
        sb.append(component.handleContent());
        sb.append("deal date:" + System.currentTimeMillis() + "\n");
        return sb.toString();
    }
}
  • 测试结果:
/**
 * @className: TestMain
 * @summary: main方法测试
 * @Description: TODO
 * @author: helon
 * date: 2018/11/18 5:08 PM
 * version: v1.0
 */
public class TestMain {
    public static void main(String[] args) {
        IPacketCreator packetCreator = new PacketDateDecorator(
                                        new PacketUserDecorator(
                                            new PacketCoreCreator()));
        System.out.println(packetCreator.handleContent());
    }
}

//执行结果:
deal date:1542532385110
deal user content begin
deal core content
deal user content end
deal date:1542532385110


Process finished with exit code 0

总结
以上就是装饰者模式的设计流程,确实是一个不错的设计模式,非常实用。其实在JDK的实现中,就有不少组件是用装饰者模式实现的,其中比较典型的例子就是OutputStream和InputStream类族的实现。比如:OutputStream类提供的方法比较简单,功能比较弱,但是通过各种装饰者的增强,OutputStream对象可以被赋予强大的功能。它的设计模式可以参考以下结构图:
OutputStream装饰器模式
其中,以OutputStream为核心的装饰者模式的实现,FileOutputStream为核心类,它实现了向文件写数据。使用DateOutputStream可以在FileOutputStream的基础上,增强对多种数据类型的写操作支持。更多的实现细节可以参考IO相关类的源码,一起学习交流,如有不正确的地方,欢迎指正批评。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值