装饰着模式,又名包装器(Wrapper)模式,用于给某个对象在运行期间动态的“升华”一些行为。
不需要事先实现子类,而是在运行期间动态加入,比子类更具灵活性,也避免了子类膨胀的危险,甚至有时候我们无法预料最终行为效果(这时使用子类无法实现),装饰者模式可以由用户来控制扩展功能的插入时机,从而对一个对象“装饰”出一些额外效果。
注意:装饰者模式不改变原有对象的行为,只是在原有行为上“添油加醋”罢了,有“如虎添翼”、“锦上添花”之功效。
使用装饰者模式可以很好地将不同维度(不同层面)上的效果叠加在一起,进而发挥出不可想象的精彩!
Java标准库中,BufferedReader(Reader in) 使用了装饰者模式,使得Reader具备了缓冲功能,FilterInputStream、FilterReader也使用装饰者模式,结合具体的装饰者角色,使得可以动态地“装饰”出一些特色功能。
场景:见面打招呼,需要注意四个方面:可以说中文或英文、语气要缓和、内容要文明、表情要友善。
分析:打招呼的几个方面:语言、语气、内容、表情分别是四个不同维度的标准,可以选择性地要求满足其中几个标准而不一定全部要求,所选标准的最终效果是叠加,
每种标准可以要求或不要求有两种选择,如果使用子类继承实现可能要出现2 * 2 * 2 *2 = 8种组合,使用装饰者非常合适。
设计:
示例代码:
interface Greet {
String doGreet();
}
class BasicGreet implements Greet{
@Override
public String doGreet() {
return "你好";
}
}
class DecoratorGreet implements Greet {
private Greet greet;
public DecoratorGreet(Greet greet) {
this.greet = greet;
}
@Override
public String doGreet() {
return greet.doGreet();
}
}
class LanguageDecorator extends DecoratorGreet {
public LanguageDecorator(Greet greet) {
super(greet);
}
@Override
public String doGreet() {
return "使用汉语," + super.doGreet();//前置
}
}
class MoodDecorator extends DecoratorGreet {
public MoodDecorator(Greet greet) {
super(greet);
}
@Override
public String doGreet() {
return "语气缓和," + super.doGreet();//前置
}
}
class ExpressionDecorator extends DecoratorGreet{
public ExpressionDecorator(Greet greet) {
super(greet);
}
@Override
public String doGreet() {
return "表情友善," + super.doGreet();//前置
}
}
class ContentDecorator extends DecoratorGreet{
public ContentDecorator(Greet greet) {
super(greet);
}
@Override
public String doGreet() {
return super.doGreet() + ", 天气不错。";//内容添加,后置
}
}
public class Test {
public static void main(String[] args) {
// 这里可以自由定义 “装饰者” 组合,以动态满足要求
Greet greet = new ExpressionDecorator(new MoodDecorator(new LanguageDecorator(new ContentDecorator(new BasicGreet()))));
System.out.println(greet.doGreet());
}
}