类结构
UML类图
初步理解
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。本例中,原本只能画圈圈,但是装饰器对现有对象进行了装饰,我们可以画出有颜色的圈圈了。
代码理解
基础接口
public interface Shape {
void draw();
}基础的接口实现类(2个)
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("只能画个圈圈");
}
}
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("只能画个框框");
}
}进行扩展的装饰类
可以看到,这个抽象类实现了Shape接口,根据传入的参数决定画哪个东西,这个也是多态的体现。
public abstract class ShapeDecorator implements Shape {
public Shape decoratedShape;
//构造函数,给Shape属性赋值
public ShapeDecorator(Shape decoratedShape){
this.decoratedShape = decoratedShape;
}
public void draw(){
decoratedShape.draw();
}
}装饰类的具体实现
抽象类里面是有方法没有实现的,因此还需要实现。
构造函数与父类的其它成员(成员变量和成员方法)不同,它不能被子类继承。因此,在创建子类对象时,为了初始化从父类中继承来的成员变量,编译器需要调用其父类的构造函数。如果子类的构造函数没有显示地调用父类的构造函数,则默认调用父类的无参构造函数。但这里需要传参数,因此需要写一个显示的构造函数,里面调用父类的构造函数。
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("现在可以染红:"+decoratedShape);
}
}出于省事的目的,这里没有重写toString方法。
测试主方法
下面的示例中,有4行加了注释,这是多态的体现。任意两行选出来都能运行。因为核心的装饰功能,在RedShapeDecorator类中,得到了实现。
public class Demo {
public static void main(String[] args) {
Shape circle = new Circle();
ShapeDecorator redCircle = new RedShapeDecorator(new Circle());
ShapeDecorator redRectangle = new RedShapeDecorator(new Rectangle());
// Shape redCircle = new RedShapeDecorator(new Circle());
// Shape redRectangle = new RedShapeDecorator(new Rectangle());
// RedShapeDecorator redCircle = new RedShapeDecorator(new Circle());
// RedShapeDecorator redRectangle = new RedShapeDecorator(new Rectangle());
System.out.println("看我接下来画什么:");
circle.draw();
System.out.println();
System.out.println("功能提升:");
redCircle.draw();
System.out.println();
System.out.println("功能提升:");
redRectangle.draw();
}
}运行结果:
看我接下来画什么: 只能画个圈圈 功能提升: 只能画个圈圈 现在可以染红:_2004装饰者模式.Circle@1b6d3586 功能提升: 只能画个框框 现在可以染红:_2004装饰者模式.Rectangle@4554617c
理解与总结:
- 一般的,我们为了扩展一个类经常使用继承方式实现,但是随着扩展功能的增多,子类会很膨胀,类的种类比较多。
- 为了解决这个问题,我们这里并没有选择扩展一个可以画红色圈圈的类,以及一个可以画红色框框的类,而是只使用了一个装饰类,就完成了上面可能用两个类才能完成的扩展,减少了类的种类。通过这个装饰的类,传入某个参数,就可以去调用具体某个类的draw方法,然后这个装饰的类内部进行了相应的功能扩展。



京公网安备 11010502036488号