一、概念
装饰者模式就是对现有类的功能进行扩展,相比继承更加灵活一些。
二、例子
图中ShapeDecorator为装饰者抽象类,里面有成员shape(也可以写到RedShapeDecorator中,图中在ShapeDecorator和RedShapeDecorator中仅有一处存在shape即可,图中两处均有,个人觉得有误)、接口的函数draw、以及构造函数来对成员Shape进行赋值。RedShapeDecorator通过继承抽象装饰类来对Shape子类的功能进行扩展,重写了draw,以及在自己的构造函数中调用对Shape进行功能扩展的函数setRedBorder()函数。
具体代码如下:
//基类接口
public interface Shape {
void draw();
}
//子类
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Shape: Rectangle");
}
}
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Shape: Circle");
}
}
//抽象装饰类
public abstract class ShapeDecorator implements Shape {
protected Shape decoratedShape;
public ShapeDecorator(Shape decoratedShape){
this.decoratedShape = decoratedShape;
}
public void draw(){
decoratedShape.draw();
}
}
//使用装饰类对Shape子类的功能进行扩展
public class RedShapeDecorator extends ShapeDecorator {
public RedShapeDecorator(Shape decoratedShape) {
ShapeDecorator(decoratedShape);
}
@Override
public void draw() {
decoratedShape.draw();
setRedBorder(decoratedShape);
}
private void setRedBorder(Shape decoratedShape){
System.out.println("Border Color: Red");
}
}
//测试类
public class DecoratorPatternDemo {
public static void main(String[] args) {
Shape circle = new Circle();
ShapeDecorator redCircle = new RedShapeDecorator(new Circle());
ShapeDecorator redRectangle = new RedShapeDecorator(new Rectangle());
System.out.println("Circle with normal border");
circle.draw();
System.out.println("\nCircle of red border");
redCircle.draw();
System.out.println("\nRectangle of red border");
redRectangle.draw();
}
}
三、优缺点
优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。
缺点:多层装饰比较复杂。
四、个人理解
装饰者模式有点类似于上一节的适配器模式的扩展。适配器模式中有成员B,并通过继承实现A的函数,在A的函数中调用B的函数。而抽象装饰类是有成员A且继承了类A,为了能扩展各式各样的功能,用了一个类C继承抽象装饰类,在C中,实现了类A的虚函数,且在虚函数中调用了成员A的虚函数并调用了C中写的针对类A扩展的功能函数。其中的成员均是通过构造函数传入类对象进行赋值(装饰者模式类C的构造函数调用了抽象装饰类的构造函数对成员A进行赋值)。
这样看装饰者模式有点类似于适配器模式的一个变形或者特例。