今天我们来介绍一种新的设计模式:Decorator(装饰器)设计模式。
什么是装饰器设计模式呢?装饰器模式的意思是:允许用户向一个现有的对象添加新的功能,同时又不改变其结构。装饰者可以在所委托被装饰者的行为之前或之后加上自己的行为,以达到特定的目的。
装饰器设计模式的一个典型的应用是Java类库中的输入输出流设计,举个例子:JavaIO中的}Output/InputStreamWriter/Reader与Output/InputStream之间的转换流,就是基于Decorator设计模式而实现的。先观察如下代码。
import java.io.*; public class Main { public static void main(String[] args)throws Exception { File file = new File("C:\\Users\\Lenovo\\Desktop\\新建文本文档.txt"); if(!file.exists()){ file.createNewFile(); } OutputStream outputStream = new FileOutputStream(file,true); Writer writer = new OutputStreamWriter(outputStream); writer.write("Output message!!!"); writer.close(); } }
这样就可以实现字节流向字符流的转换了,现在我们来看一下类继承关系图。
我们通过代码和类关系图可以发现OutputStream类型是可以作为参数传入OutputStreamWriter的。就相当于OutputStreamWriter在不改变OutputStream的前提下,扩展了一些功能。IntputStreamReader也是同样的道理,这就是装饰器设计模式的典型例子。
接下来介绍一下这种设计模式的思路以及设计理念。首先看一下类继承的结构框图。
首先对这张图做一些介绍
1:抽象组件(Component):需要装饰的抽象对象。
2:具体组件(ConcreteComponent):是我们需要装饰的对象
3:抽象装饰类(Decorator):内含指向抽象组件的引用及装饰者共有的方法。
4:具体装饰类(ConcreteDecorator):被装饰的对象。
现在我们举一个例子来简单的实现这种设计模式:假设需要装饰的类中有一个字符串需要被装饰,我们现在要通过使用装饰器设计模式来装饰这个字符串。我们来看下面的实现代码。
interface Component{//需要装饰的类的接口 void Decorator_Count(); void CreateMessage(String Decorator); } class ConcreteComponent implements Component{//需要装饰的具体类 private String Message = "需要装饰的类 "; private int Count = 0; @Override public void Decorator_Count() {//返回被装饰的次数 this.Count++; } @Override public void CreateMessage(String Decorator) {//返回装饰结果 this.Message+= Decorator; } public String getMessage() { return Message; } public int getCount() { return Count; } } abstract class Decorator implements Component{//装饰类,因为需要装饰被装饰类,所以与其继承同一接口 private Component DClass;//定义私有属性储存需要装饰的类 public Decorator(Component DClass){//构造注入需要装饰的类 this.DClass = DClass; } @Override public void Decorator_Count() {//调用要装饰的类的方法 this.DClass.Decorator_Count(); } @Override public void CreateMessage(String Decorator) {//同上 this.DClass.CreateMessage(Decorator); } } class ConcreteDecorator extends Decorator{//具体装饰组件,继承于装饰类 public ConcreteDecorator(Component component){//要装饰的时候调用装饰类的构造注入。 super(component); } @Override public void Decorator_Count() { super.Decorator_Count(); } @Override public void CreateMessage(String Decorator) {//由用户决定添加的装饰组件 super.CreateMessage(Decorator); Decorator_Count(); } } public class Main{ public static void main(String[] args){ ConcreteComponent ConcreteComponent = new ConcreteComponent();//创建要装饰的类对象 new ConcreteDecorator(ConcreteComponent).CreateMessage(" 装饰A "); new ConcreteDecorator(ConcreteComponent).CreateMessage(" 装饰B "); new ConcreteDecorator(ConcreteComponent).CreateMessage(" 装饰C "); System.out.println("装饰之后的装饰类 : ["+ConcreteComponent.getMessage()+"] 装饰次数 : "+ConcreteComponent.getCount()); } }
现在相当于往要装饰的类中的需要被修饰的字符串增加了三段字符串。我们来看结果
这种设计模式的使用场景就是当我们有需求要去动态的增加或者减少类对象的功能。
Decorator设计模式的优点是:
1:装饰类和被装饰类耦合性低。
2:灵活,被装饰者可以灵活组装需要的属性(类)。
缺点是:
1:类结构复杂,含有大量的其他类。
有关Decorator设计模式就先总结到这里,后续会有补充。