装饰器(Decorator)模式:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责的模式
优点:
- 装饰器是继承的补充,相对灵活,在不改变原有功能的前提下,扩展一个对象的功能
- 通过使用不同的装饰类,可以实现不同的功能
- 遵循开闭原则
缺点:会增加很多类
通常情况下,扩展一个类常常使用继承来实现,但是不能忽视继承会带来的一些问题
- 继承是静态的。 你无法在运行时更改已有对象的行为, 只能使用由不同子类创建的对象来替代当前的整个对象。
- 子类只能有一个父类。 大部分编程语言不允许一个类同时继承多个类的行为。
其中一种方法是用聚合或组合 , 而不是继承。 两者的工作方式几乎一模一样: 一个对象包含指向另一个对象的引用, 并将部分工作委派给引用对象; 继承中的对象则继承了父类的行为, 它们自己能够完成这些工作。
你可以使用这个新方法来轻松替换各种连接的 “小帮手” 对象, 从而能在运行时改变容器的行为。 一个对象可以使用多个类的行为, 包含多个指向其他对象的引用, 并将各种工作委派给引用对象。 聚合 (或组合) 组合是许多设计模式背后的关键原则 (包括装饰在内)
“装饰器” 是一个能与其他 “目标” 对象连接的对象。 装饰器包含与目标对象相同的一系列方法, 它会将所有接收到的请求委派给目标对象。 但是, 装饰器可以在将请求委派给目标前后对其进行处理, 所以可能会改变最终结果。
具体结构
- 抽象构件:定义一个抽象接口以规范准备接收附加责任的对象
- 具体构件:实现抽象构件,通过装饰器为其添加一些职责
- 抽象装饰:继承抽象构件,并包含有具体构件的实例,可以通过其子类扩展具体构件的功能
- 具体装饰:实现抽象装饰相关的方法,并给具体构件对象添加附加职责
举例:假设我们目前有个绘制图形的功能,现在要给某些图形附加颜色的职责
public class DecoratorDemo {
// 形状
interface Shape {
void draw();
}
// 圆形
static class Circle implements Shape{
@Override
public void draw() {
System.out.println("绘制圆形");
}
}
// 装饰器
abstract static class ColorDecorator implements Shape {
private Shape shape;
public ColorDecorator(Shape shape){
this.shape = shape;
}
@Override
public void draw() {
this.shape.draw();
}
public abstract void addColor();
}
// 装饰颜色
static class BlueCircle extends ColorDecorator{
public BlueCircle(Shape shape) {
super(shape);
}
@Override
public void addColor() {
System.out.println("添加蓝色");
this.draw();
}
}
public static void main(String[] args) {
ColorDecorator colorDecorator = new BlueCircle(new Circle());
colorDecorator.addColor();
}
}