作用:对原有功能向多个方向进行扩展,每一个扩展是一个具体的装饰角色,就像孙悟空七十二变一样,变化的每一个角色都是一个具体的装饰角色!类似代理模式的作用!既可以提供动态代理的“统一服务”,也可以提供静态代理的“个性化服务”,妙啊!
上班族大多都有睡懒觉的习惯,每天早上上班时间都很紧张,于是很多人为了多睡一会,就会用方便的方式解决早餐问题。有些人早餐可能会吃煎饼,煎饼中可以加鸡蛋,也可以加香肠,但是不管怎么“加码”,都还是一个煎饼。在现实生活中,常常需要对现有产品增加新的功能或美化其外观,如房子装修、相片加相框等,都是装饰器模式。 在软件开发过程中,有时想用一些现存的组件。这些组件可能只是完成了一些核心功能。但在不改变其结构的情况下,可以动态地扩展其功能。所有这些都可以釆用装饰器模式来实现。 设计模式之间都是相通的,对原有的功能进行扩展的方法有很多。比如Java代码复用的三种常用方式:继承、组合和代理;还比如适配器模式,你缺啥我给你适配啥;这个装饰器模式也是一种扩展方式!
装饰器(Decorator)模式:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。
装饰器模式会增加许多子类,过度使用会增加程序得复杂性;
装饰器模式所包含的 4 个角色不是任何时候都要存在的,在有些应用环境下模式是可以简化的:
抽象构件角色就相当于一个装饰器,谁要装饰say()方法就实现我这个接口 比如说这是个快递,我写个统一的包装方法,谁要包装实现我即可
package com.zibo.design.eleven;
// 抽象构件角色:孙悟空
// 抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象;
public interface SunWuKong {
void say();
}
具体构件角色就相当于想要装饰自己的具体角色,比如说快递需要装箱,实现装箱接口即可
package com.zibo.design.eleven;
// 具体构件角色:猴子
// 具体构件(ConcreteComponent)角色:实现抽象构件,通过装饰角色为其添加一些职责;
public class Monkey implements SunWuKong {
@Override
public void say() {
System.out.println("我本是一只猴子!");
}
}
这个是抽象装饰角色,就相当于一个快递的常规包装流程,装个普通的箱子; 这有一个非常妙的点:可以在抽象装饰里面提供“统一的服务”(动态代理功能); 这个抽象装饰角色不一定要写成一个抽象类(教程就没写,我自己写的) SunWuKong sunWuKong = new Changer(monkey); sunWuKong.say(); // 仅需要统一服务
package com.zibo.design.eleven;
// 抽象装饰角色:Changer
// 抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,
// 可以通过其子类扩展具体构件的功能;
public abstract class Changer implements SunWuKong{
private final SunWuKong sunWuKong;
public Changer(SunWuKong sunWuKong) {
this.sunWuKong = sunWuKong;
}
@Override
public void say() {
// 方法前统一服务
sunWuKong.say();
// 方法后统一服务
}
}
具体装饰角色,相当于这是贵重易损物品,仅仅装个箱子还不够,需要再在外部价格木盒子 这有一个非常妙的点:可以在具体装饰类之内提供“个性化服务”(静态代理功能);
package com.zibo.design.eleven;
// 具体装饰角色:美女
public class Beauty extends Changer {
public Beauty(SunWuKong sunWuKong) {
super(sunWuKong);
}
@Override
public void say() {
// 方法前个性服务
super.say();
// 方法后个性服务
System.out.println("我变成了大美女!");
}
}
package com.zibo.design.eleven;
// 具体装饰角色:龙
public class Dragon extends Changer {
public Dragon(SunWuKong sunWuKong) {
super(sunWuKong);
}
@Override
public void say() {
super.say();
System.out.println("我变成了一条龙!");
}
}
package com.zibo.design.eleven;
public class Test {
public static void main(String[] args) {
Monkey monkey = new Monkey();
monkey.say();
SunWuKong beauty = new Beauty(monkey);
beauty.say();
SunWuKong dragon = new Dragon(monkey);
dragon.say();
}
}
我本是一只猴子!
我本是一只猴子!
我变成了大美女!
我本是一只猴子!
我变成了一条龙!