设计模式之装饰者模式
装饰者模式又叫包装模式,定义如下:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰者模式相比生成子类来说更为灵活。
装饰者模式的类图如上:
从图中可以看到装饰着模式涉及到四个角色:
1.抽象构件角色Component
Component可以是一个接口或者抽象类,主要是定义一些规则
2.具体构件角色ConcreteComponent
ConcreteComponent是抽象构件的实现类同时也是被装饰的对象
3.Decorator抽象装饰者角色
一般是一个抽象者对象,同时实现抽象构件角色中定义的功能,并且含有一个私有属性执行抽象构件
4.具体装饰者角色
主要是用来装饰具体构件角色
/** * 抽象构件 * */ public abstract class Component { // 抽象方法 protected abstract void operation(); }
/** * 具体构件 * */ public class ConcreteComponent extends Component { /** * */ @Override protected void operation() { System.out.println("Hello World!"); } }
public abstract class Decorator extends Component { private Component component; public Decorator(Component component) { this.component = component; } /** * */ @Override protected void operation() { component.operation(); } }
public class ConcreteDecorator extends Decorator { /** * @param component */ public ConcreteDecorator(Component component) { super(component); } // 装饰方法 private void doSomething() { System.out.println("装饰"); } @Override protected void operation() { doSomething(); super.operation(); } }
public class Client { public static void main(String[] args) { //被装饰者 Component component=new ConcreteComponent(); //装饰者 Decorator decorator=new ConcreteDecorator(component); //装饰 decorator.operation(); } }
看完装饰模式大家可能会有一些疑问,不就是要重新扩张一个方法的功能吗?我直接集成具体构件类重写里面的方法不就行了吗?其实装饰者模式是继承关系的一种替代方案,集成是一种高侵入性的,况且我们做开发的也知道,需求是无止境的,你根本不知道用户的需求最终会变成什么样,也许有一天需求变了,那么你难道还要再次集成然后重写里面的方法吗?
装饰者模式的优点:
1.装饰类和被装饰的对象可以独立发展不必互相耦合
2.装饰者模式是继承关系的一种替代
当然装饰者模式也是有缺点的,那就是装饰者的实现类可能会出现类膨胀的情况的,所以是否需要使用装饰者模式就要看具体的情况了。
装饰的使用场景
1.需要扩展一个类的功能或给一个类增加附加功能
2.需要动态的给一个对象增加功能并且这些功能可以动态的撤销
3.需要为一批兄弟类进行改装或增加功能
相信大家都做过文件上传获取其他和IO相关的操作,其实java IO中主要使用模式就是装饰者模式,大家可以想象上面的问题,如果为了增强一个类的功能我们就使用继承的话,那么java IO的实现如果使用继承一定会很可怕的.....
下面是一张java IO使用装饰者模式的简单类图: