Decorator(装饰)
意图:动态的给一个对象添加一些额外的职责。就添加功能来说,Decorator模式相比生成子类更为灵活
结构图:
在以下情况适合使用
- 在不影响其他对象的情况下,以动态,透明的方式给单个对象添加职责
- 处理那些可以撤销的职责
- 当不能采用生成子类的方法进行扩充时,一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是,类定义被隐藏,或类定义不能用于生成子类。
实现:
就添加功能,扩展父类来说,装饰模式要比继承要灵活,而且可以有效避免类的爆炸。并且可以动态的增加职责。
有一部普通的手机,只能打电话,若是要加一个铃声功能,可以通过继承父类,子类去实现。若是要想接听振动,还可以在继承,在实现,若是又要铃声又要振动。。。。。
通过继承来实现功能的扩展,功能的组合方式越多,类的结构越复杂,类的数量越多,而且不能支持动态的增加减少职责。
装饰模式就可以给对象动态的添加职责。
phone
public abstract class Phone {
abstract void call();
}
NormalPhone普通手机
public class NormalPhone extends Phone {
@Override
void call() {
System.out.println("打电话");
}
}
PhoneDecorate 装饰器
public class PhoneDecorate extends Phone {
@Override
void call() {
}
}
BellPhoneDecorate 铃声装饰器
public class BellPhoneDecorate extends PhoneDecorate {
private Phone phone;
public BellPhoneDecorate(Phone phone) {
this.phone = phone;
}
@Override
void call() {
phone.call();
System.out.println("铃声ing....");
}
}
VibrancyPhoneDecorate 振动修饰
public class VibrancyPhoneDecorate extends PhoneDecorate {
private Phone phone;
public VibrancyPhoneDecorate(Phone phone) {
this.phone = phone;
}
@Override
void call() {
phone.call();
System.out.println("振动ing....");
}
}
Main
public class Main {
public static void main(String[] args) {
Phone normalPhone = new NormalPhone();
System.out.println("普通手机");
normalPhone.call();
Phone bellPhone = new BellPhoneDecorate(normalPhone);
System.out.println("铃声手机");
bellPhone.call();
Phone bellAndVPhone =
new VibrancyPhoneDecorate( new BellPhoneDecorate(normalPhone));
System.out.println("三体合一手机");
bellAndVPhone.call();
}
}
相关模式
Adapter:Decorator模式不同于Adapter模式,因为装饰进改变对象的职责而不改变他的接口;而适配器将给对象一个全新的接口
Composite:可以将装饰视为一个退化的,仅有一个组件的组合。然而,装饰仅给对象添加一些额外的职责,他的目的不在于对象聚集
Strategy:用一个装饰可以改变对象的外表;而Strategy模式使得你可以改变对象的内核。这是改变对象的两种途径。