Java设计模式之再从[暗黑破坏神"装备镶嵌宝石系统"]分析装饰(Decorator)模式
来源:互联网 发布:在c语言中char型数据 编辑:程序博客网 时间:2024/04/28 03:20
在暗黑破坏神等RPG游戏中,会遇到如下的一些场景:我有一把很普通的武器,我通过给它“注入魔法力量”、“镶嵌宝石”,来使得它拥有一些攻击特效:例如,一把普通长剑,镶嵌红宝石后,可以附带火焰伤害,镶嵌了一个蓝宝石后,可以使得长剑攻击带有冰冻伤害。
如何实现上述的机制呢?首先我们想到的是继承,因为,一个镶嵌了红宝石、蓝宝石的长剑,一定是一个镶嵌了宝石的长剑,并且一定一把长剑。如此下来,程序的结构会很复杂,而且你可能会想,要是镶嵌的是别的宝石怎么办呢?如果出了宝石外,可以镶嵌其他物品(如符文),那是不是应该把继承的结构改变呢?可见,继承并不是一个最优的方案。
仔细分析一下这种情况,我们会发现,所谓“火焰伤害”、“冰冻伤害”,只是一些“攻击特效”,说白了就是长剑的攻击的装饰。我们仅仅是为了能够在长剑攻击的时候,增加一些职责:触发火焰伤害、触发冰冻伤害。这个时候我们就可以用到装饰(Decorator)模式——它的意图是动态地给一个对象添加一些额外的职责。就增加新功能来说,它比继承更为灵活。
假设我想给我的长剑赋予眩晕、暴击和中毒攻击三种特效,那么Java代码可以这样写:
interface Weapon{ void printInfo();}class Sword implements Weapon { public void printInfo(){ System.out.println ("一把长剑"); }}abstract class WeaponDecorator implements Weapon { public Weapon weapon; public WeaponDecorator(Weapon _weapon){ weapon = _weapon; } public void printInfo(){ weapon.printInfo(); }}class PoisonDecorator extends WeaponDecorator { public PoisonDecorator(Weapon _weapon) { super(_weapon); } public void printInfo() { weapon.printInfo(); //以下是自己添加的方法(装饰) System.out.println(" 有50%几率造成敌人中毒"); }}class CriticalDecorator extends WeaponDecorator { public CriticalDecorator(Weapon _weapon) { super(_weapon); } public void printInfo() { weapon.printInfo(); //以下是自己添加的方法(装饰) System.out.println(" 有50%几率造成致命一击"); }}class DazzleDecorator extends WeaponDecorator { public DazzleDecorator(Weapon _weapon) { super(_weapon); } public void printInfo() { weapon.printInfo(); //以下是自己添加的方法(装饰) System.out.println(" 有50%几率造成敌人眩晕"); }}class Decorator{ public static void main(String[] args) { Weapon superWeapon = new DazzleDecorator(new CriticalDecorator(new PoisonDecorator(new Sword()))); superWeapon.printInfo(); }}
武器都继承于Weapon接口,此接口声明了一个方法:printInfo(),将武器的信息打印出来。我们的装饰器类WeaponDecorator中,包含了一个原始的Weapon对象引用,接下来是重点:当调用装饰器类的printInfo时,它会先调用Weapon对象的printInfo,然后再调用自己额外增加的一些代码。当然,调用Weapon.printInfo的顺序可先可后,但是一定会调用到。也就是说,装饰器类的重点是其中包含一个原始对象,在调用某个方法时,装饰器类不仅仅会调用原始对象的这个方法,你还可以自己给它增加一些方法。如本例中,调用装饰器类的printInfo时,先调用了weapon.printInfo(),再调用了我们希望它增加的职责System.out.println,那么代码运行结果如下:
一把长剑
有50%几率造成敌人中毒
有50%几率造成致命一击
有50%几率造成敌人眩晕
装饰模式比继承模式更加灵活(可以灵活添加职责),然而,我们必须要为每一个被装饰的方法新建一个类,如果需要装饰的方法很多,那么我们会需要建立数量巨大的装饰器类,这个时候就要考虑是否要用装饰模式了。在Java.IO,C#的IO(如OutputStream)中就用到了装饰器这种模式。需要注意到是,装饰器类必须要与被装饰的类继承于同一接口,这就如最开始所说的,不管长剑镶嵌了什么,它总是一把武器。
- Java设计模式之再从[暗黑破坏神"装备镶嵌宝石系统"]分析装饰(Decorator)模式
- Java设计模式之从[暗黑破坏神"装备镶嵌宝石系统"]分析桥接(Bridge)模式
- java设计模式之装饰模式Decorator
- JAVA设计模式之装饰模式(decorator)
- java设计模式之Decorator(装饰)模式
- Java设计模式之从[暗黑破坏神存档点]分析备忘录(Memento)模式
- java.io.*中的设计模式之 装饰(Decorator)模式
- java设计模式之装饰者模式Decorator
- JAVA设计模式之 装饰模式【Decorator Pattern】
- Java设计模式透析之 ——装饰模式(Decorator )
- Java设计模式之装饰者模式(Decorator pattern)
- 设计模式之decorator装饰模式
- 设计模式之-Decorator--装饰器模式
- 设计模式之Decorator(装饰者模式)
- 设计模式之(三、装饰模式Decorator)
- 设计模式之(九)装饰模式Decorator
- 设计模式之Decorator(装饰模式)
- 设计模式之装饰模式(Decorator Pattern)
- 关于LWIP_1.4.1在STM32平台移植后大数据包ping不通问题
- MAT使用实例
- poj3938 Portal 并查集
- 网络131第3周实验——循环与判断语句
- 软考复习之路——数据结构与算法概览
- Java设计模式之再从[暗黑破坏神"装备镶嵌宝石系统"]分析装饰(Decorator)模式
- 排列组合枚举代码
- Java虚拟机内存模型
- MMU的理解
- 距离类的成员函数,友元函数,一般函数
- 不能声明为虚函数的函数(转)
- Prim算法学习
- Unity3D获取网络时间,解析xml/截取string
- 如何不浪费网站流量 网站做好二次营销的几个方案