1.装饰器模式的概念
装饰器模式(Decorator Pattern)允许像一个显示有的对象添加新功能,同时又不改变其结构;是对现有类的一个包装
创建一个装饰类,来包装原有的类,比如说汽车已经有行驶的功能了,我想锦上添花,在车上加个音箱,这样是不是帅呆了。
- 作用:动态地给一个对象增加新的功能
- 要解决的问题:其实看到新增功能这几个字,我们应该想到JAVA中的三大特性中的继承,也可以实现类似的功能,那么为什么还要用装饰器模式呢。这是因为随着我们的系统的扩展,如果我们不断继承的话,子类会越来越多,难以管理
- 如何实现:
1、Component 类充当抽象角色,不应该具体实现。
2、修饰类引用和继承 Component 类,具体扩展类重写父类方法。
优点:解耦合,不会影响原本的类,是继承的一个替代模式
缺点:如果功能过多,多层装饰会很麻烦
2.实现
step1:
我们还是按图上说的先定义一个Shape接口,和两个实现类;
public interface Shape {
void draw();
}
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("This is rectangle");
}
}
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("This is Circle");
}
}
step2:
装饰器类
public abstract class ShapeDecorator implements Shape{
protected Shape decoratedShape;
public ShapeDecorator(Shape decoratedShape) {
this.decoratedShape = decoratedShape;
}
public void draw(){
decoratedShape.draw();
}
}
step3:
这里我们就要扩展新的功能了
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");
}
}
step4:
测试程序
public class DecoratorPatternDemo {
public static void main(String[] args) {
Shape circle = new Circle();
Shape readCircle = new RedShapeDecorator(new Circle());
System.out.println("Circle with normal border");
circle.draw();
System.out.println("Circle of red border");
readCircle.draw();
}
}
3.总结:
其实我们从上面一个简简单单的实例来看,貌似和继承也没多少差别。而且从代码理解上来看,直接继承省心省力多了。但是,我们想想,如果我们的系统越来越大了,要继承的类越来越多,那么我们的.java文件也会越来越多,也许某天你要改功能了就要满世界找,这很影响效率,而如果我们集中在一个装饰类里面管理的话,那将会非常简单,想加啥,减啥,都非常简单,毕竟你全部东西都写在那了,不用看满天的子类了。
比较经典的装饰器的应用我们可以看看JAVA 的IO的源码~
参考:
http://www.runoob.com/design-pattern/decorator-pattern.html