动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更 为灵活。
抽象组件
public abstract class Sowrdsman {
public abstract void attackMagic();
}
组件的具体实现类
public class YangGuo extends Sowrdsman{
@Override
public void attackMagic() {
System.out.println("杨过使用全真剑法");
}
}
抽象装饰者
抽象装饰者保持了一个对抽象组件的引用,方便调用被装饰对象中的方法。
public abstract class Master extends Sowrdsman{
private Sowrdsman sowrdsman;
public Master(Sowrdsman sowrdsman) {
this.sowrdsman = sowrdsman;
}
@Override
public void attackMagic() {
sowrdsman.attackMagic();
}
}
装饰者具体实现类
public class HongQiGong extends Master {
public HongQiGong(Sowrdsman sowrdsman) {
super(sowrdsman);
}
public void teachAttackMagic(){
System.out.println("洪七公教授打狗棒法");
System.out.println("杨过使用打狗棒法");
}
@Override
public void attackMagic() {
super.attackMagic();
teachAttackMagic();
}
}
public class OuYangFeng extends Master {
public OuYangFeng(Sowrdsman sowrdsman) {
super(sowrdsman);
}
public void teachAttackMagic(){
System.out.println("欧阳锋教授蛤蟆功");
System.out.println("杨过使用蛤蟆功");
}
@Override
public void attackMagic() {
super.attackMagic();
teachAttackMagic();
}
}
客户端
public static void main(String[] args) {
// 被装饰者
YangGuo mYangGuo = new YangGuo();
//洪七公向杨过传授打狗棒法,杨过学会了打狗棒法
HongQiGong mHongQiGong=new HongQiGong(mYangGuo);
mHongQiGong.attackMagic();
//欧阳锋向杨过传授蛤蟆功,杨过学会了蛤蟆功
OuYangFeng mOuYangFeng=new OuYangFeng(mYangGuo);
mOuYangFeng.attackMagic();
}
装饰者模式优缺点
优点:
- 通过组合而非继承的方式,动态地扩展一个对象的功能,在运行时选择不同的装饰 器,从而实现不同的行为。
- 有效避免了使用继承的方式扩展对象功能而带来的灵活性差、子类无限制扩张的问题。
- 具体组件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体组件类和 具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开放封闭原则”。
缺点:
- 如果基类改变,则势必影响对象的内部。
- 对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。所 以,只在必要的时候使用装饰模式。
- 装饰层数不能过多,否则会影响效率。