设计模式——装饰模式
一、什么是装饰模式
装饰模式(Decorator),动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更灵活。UML结构图如 下:
Component是抽象构件,定义一个对象接口,可以给这些对象动态地添加职责;
ConcreteComponent定义一个具体对象,也可以给这个对象添加一些职责;
Decorator是装饰抽象类,实现接口或抽象方法;
ConcreteDecorator是具体装饰对象,起到给Component添加职责的功能。
二、原码实现
- Component抽象类
public abstract class Component {
public abstract void operation();
}
- ConcreteComponent 具体对象
public class ConcreteComponent extends Component {
@Override
public void operation() {
System.out.println("具体对象的操作");
}
}
- Decorator 装饰类
public abstract class Decorator extends Component {
private Component component = null;
//通过构造函数传递给被修饰者
public Decorator(Component component) {
this.component = component;
}
//委托给被修饰者执行
@Override
public void operation() {
if(component != null) {
this.component.operation();
}
}
}
- ConcreteDecorator 具体装饰类
public class ConcreteDecoratorB extends Decorator {
//定义被修饰者
public ConcreteDecoratorB(Component component) {
super(component);
}
//定义自己的修饰方法
private void method2() {
System.out.println("method2 修饰");
}
@Override
public void operation() {
super.operation();
this.method2();
}
}
-
Test测试类
public class Client { public static void main(String[] args) { Component component = new ConcreteComponent(); //第一次修饰 component = new ConcreteDecoratorA(component); //第二次修饰 component = new ConcreteDecoratorB(component); //修饰后运行 component.operation(); } }
三、装饰模式的应用
1. 何时使用
- 在不想增加很多子类的情况下扩展类时
2. 方法
- 将具体功能职责划分,同时继承装饰者模式
3. 优点
- 装饰类和被装饰类可以独立发展,而不会相互耦合。它有效地把类的核心职责和装饰功能分开了
- 装饰模式是继承关系的一个替代方案
- 装饰模式可以动态地扩展一个实现类的功能
4. 缺点
- 多层装饰比较复杂。比如我们现在有很多层装饰,出了问题,一层一层检查,最后发现是最里层的装饰出问题了,想想工作量都害怕
5. 使用场景
- 需要扩展一个类的功能时
- 需要动态地给一个对象增加功能,并可以动态地撤销时
- 需要为一批的兄弟类进行改装或加装功能时
6. 应用实例
- 旧机包装成新机,手机/电脑内部配件不变,只是换个外壳
- 换衣小游戏,人还是那个人,不断给她换衣服,还可以一层套一层的
- 孙悟空有72变,变成什么后就有了它的功能,但本质还是一只猴子
四、问题解决
利用装饰模式设计一个会扫地的机器人Robot,要求:
1.不修改Robot源码的基础上,改进该机器人,使其在扫地前说话“主人,我开始工作了哦!”;
2.不修改原有代码的基础上,再次改进该机器人,使其在扫地前判断地面是否需要清洁;
3.不增加任何源码的基础上,动态增加机器人的功能,使该机器人具备以下功能:
a)先判断地面是否需要清洁;
b)扫地前说话“主人,我开始工作了哦!”;
c)扫地;
4.绘制uml类图,代码实现后测试。