相关文章 设计模式之设计六大原则 设计模式之单例模式的七种写法 设计模式之建造者模式 设计模式之简单工厂模式 设计模式之观察者模式 设计模式之代理模式
装饰模式是结构型设计模式之一,不必改变类文件和使用继承的情况下,动态地扩展一个对象的功能,是继承的替代方案之一。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
装饰模式在现实生活中有很多例子,比如给一个人穿上各种衣服,给一幅画涂色上框等等,这次我要举得例子有些不同,举一个武侠修炼武功的例子:杨过本身就会全真剑法,有两位武学前辈洪七公和欧阳锋分别传授杨过打狗棒法和蛤蟆功,这样杨过除了会全真剑法还会打狗棒法和蛤蟆功。
作为武侠肯定要会使用武功的,我们先定义一个武侠的抽象类,里面有使用武功的抽象方法:
public abstract class Swordsman {
/**
* Swordsman武侠有使用武功的抽象方法
*/
public abstract void attackMagic();
}
被装饰的具体对象,在这里就是被教授武学的具体的武侠,他就是杨过,杨过作为武侠当然也会武学,虽然不怎么厉害:
public class YangGuo extends Swordsman{
@Override
public void attackMagic() { //杨过初始的武学是全真剑法
System.out.println("杨过使用全真剑法");
}
}
抽象装饰者保持了一个对抽象组件的引用,方便调用被装饰对象中的方法。在这个例子中就是武学前辈要持有武侠的引用,方便教授他武学并“融会贯通”:
public abstract class Master extends Swordsman{
private Swordsman mSwordsman; public Master(Swordsman mSwordsman){ this.mSwordsman=mSwordsman;
} @Override
public void attackMagic() {
mSwordsman.attackMagic();
}
}
这个例子中用两个装饰者具体实现类,分别是洪七公和欧阳锋,他们负责来传授杨过新的武功:
public class HongQiGong extends Master {
public HongQiGong(Swordsman mSwordsman) { super(mSwordsman);
} public void teachAttackMagic(){
System.out.println("洪七公教授打狗棒法");
System.out.println("杨过使用打狗棒法");
} @Override
public void attackMagic() { super.attackMagic();
teachAttackMagic();
}
}
public class OuYangFeng extends Master {
public OuYangFeng(Swordsman mSwordsman) { super(mSwordsman);
} public void teachAttackMagic(){
System.out.println("欧阳锋教授蛤蟆功");
System.out.println("杨过使用蛤蟆功");
} @Override
public void attackMagic() { super.attackMagic();
teachAttackMagic();
}
}
经过洪七公和欧阳锋的教导,杨过除了初始武学全真剑法又学会了打狗棒法和蛤蟆功:
public class Client { public static void main(String[] args){ //创建杨过
YangGuo mYangGuo=new YangGuo(); //洪七公教授杨过打狗棒法,杨过会了打狗棒法
HongQiGong mHongQiGong=new HongQiGong(mYangGuo);
mHongQiGong.attackMagic(); //欧阳锋教授杨过蛤蟆功,杨过学会了蛤蟆功
OuYangFeng mOuYangFeng=new OuYangFeng(mYangGuo);
mOuYangFeng.attackMagic();
}
}
在上一篇文章设计模式之代理模式中我们讲到了代理模式,你会觉得代理模式和装饰模式有点像,都是持有了被代理或者被装饰对象的引用。它们两个最大的不同就是装饰模式对引用的对象增加了功能,而代理模式只是对引用对象进行了控制却没有对引用对象本身增加功能。