透析管理系统java_Java设计模式透析之 ——装饰模式(Decorator )

今天继续设计模式之旅,给大家带来装饰者模式,国际惯例,先看定义。

装饰者模式:若要扩展功能,装饰者提供了比集成更有弹性的替代方案,动态地将责任附加到对象上。

先简单描述下装饰者模式发挥作用的地方,当我们设计好了一个类,我们需要给这个类添加一些辅助的功能,并且不希望改变这个类的代码,这时候就是装饰者模式大展雄威的时候了。这里还体现了一个原则:类应该对扩展开放,对修改关闭。

下面进入正题,今天在那看电影,忽然想起年轻时在游戏场上的血雨腥风啊,哈哈,下面以游戏为背景介绍装饰者模式。玩过游戏的兄弟应该都知道,游戏里面每个角色有武器、鞋子、护腕、戒指、还有各种红宝石、蓝宝石、黄宝石等等。

下面需求开始:设计游戏的装备系统,基本要求,要可以计算出每种装备在镶嵌了各种宝石后的攻击力和描述:

具体需求:

1、武器(攻击力20) 、戒指(攻击力5)、护腕(攻击力5)、鞋子(攻击力5)

2、蓝宝石(攻击力5/颗)、黄宝石(攻击力10/颗)、红宝石(攻击力15/颗)

3、每个装备可以随意镶嵌3颗

好了,需求介绍完毕,当然了,不要吐槽我的设计,尼玛鞋子哪来的攻击力,关键时刻也是可以砸人的嘛。下面开始初步的设想,出于多年面向对象的经验,我们可能会这么设计:

0818b9ca8b590ca3270a3433284dd417.png

如果你这么设计了,我靠,就这么点需求你写了几百个类,随便添加两个宝石,哈哈,指数增长听过么,准备加班吧。

可能你还会这么设计:写一个超类,然后里面各种set宝石,然后在计算攻击力的地方,使劲的If有哪几种宝石,恭喜你,代码量不是很大,但是随便添加个武器,你得又多写多少个IF呢。

上面叙述了一些可能性的设计,都不是很好,下面看看如何将装饰者模式融入:

首先是装备的超类

packagecom.zhy.pattern.decorator;

/**

* 装备的接口

*

* @author zhy

*

*/

publicinterfaceIEquip

{

/**

* 计算攻击力

*

* @return

*/

publicintcaculateAttack();

/**

* 装备的描述

*

* @return

*/

publicString description();

}

然后分别是武器、戒指、护腕、鞋子

packagecom.zhy.pattern.decorator;

/**

* 武器

* 攻击力20

* @author zhy

*

*/

publicclassArmEquipimplementsIEquip

{

@Override

publicintcaculateAttack()

{

return20;

}

@Override

publicString description()

{

return"屠龙刀";

}

}

packagecom.zhy.pattern.decorator;

/**

* 戒指

* 攻击力 5

* @author zhy

*

*/

publicclassRingEquipimplementsIEquip

{

@Override

publicintcaculateAttack()

{

return5;

}

@Override

publicString description()

{

return"圣战戒指";

}

}

packagecom.zhy.pattern.decorator;

/**

* 护腕

* 攻击力 5

* @author zhy

*

*/

publicclassWristEquipimplementsIEquip

{

@Override

publicintcaculateAttack()

{

return5;

}

@Override

publicString description()

{

return"圣战护腕";

}

}

packagecom.zhy.pattern.decorator;

/**

* 鞋子

* 攻击力 5

* @author zhy

*

*/

publicclassShoeEquipimplementsIEquip

{

@Override

publicintcaculateAttack()

{

return5;

}

@Override

publicString description()

{

return"圣战靴子";

}

}

接下来当然是装饰品,宝石了,首先超类

packagecom.zhy.pattern.decorator;

/**

* 装饰品的接口

* @author zhy

*

*/

publicinterfaceIEquipDecoratorextendsIEquip

{

}

下来蓝宝石、黄宝石、红宝石

packagecom.zhy.pattern.decorator;

/**

* 蓝宝石装饰品

* 每颗攻击力+5

* @author zhy

*

*/

publicclassBlueGemDecoratorimplementsIEquipDecorator

{

/**

* 每个装饰品维护一个装备

*/

privateIEquip equip;

publicBlueGemDecorator(IEquip equip)

{

this.equip = equip;

}

@Override

publicintcaculateAttack()

{

return5+ equip.caculateAttack();

}

@Override

publicString description()

{

returnequip.description() +"+ 蓝宝石";

}

}

packagecom.zhy.pattern.decorator;

/**

* 黄宝石装饰品

* 每颗攻击力+10

* @author zhy

*

*/

publicclassYellowGemDecoratorimplementsIEquipDecorator

{

/**

* 每个装饰品维护一个装备

*/

privateIEquip equip;

publicYellowGemDecorator(IEquip equip)

{

this.equip = equip;

}

@Override

publicintcaculateAttack()

{

return10+ equip.caculateAttack();

}

@Override

publicString description()

{

returnequip.description() +"+ 黄宝石";

}

}

packagecom.zhy.pattern.decorator;

/**

* 红宝石装饰品 每颗攻击力+15

*

* @author zhy

*

*/

publicclassRedGemDecoratorimplementsIEquipDecorator

{

/**

* 每个装饰品维护一个装备

*/

privateIEquip equip;

publicRedGemDecorator(IEquip equip)

{

this.equip = equip;

}

@Override

publicintcaculateAttack()

{

return15+ equip.caculateAttack();

}

@Override

publicString description()

{

returnequip.description() +"+ 红宝石";

}

}

好了,到此结束,我们已经实现了需求的功能了,是不是每个类都很清晰加简单,下面看测试:

packagecom.zhy.pattern.decorator;

publicclassTest

{

publicstaticvoidmain(String[] args)

{

// 一个镶嵌2颗红宝石,1颗蓝宝石的靴子

System.out.println(" 一个镶嵌2颗红宝石,1颗蓝宝石的靴子");

IEquip equip = newRedGemDecorator(newRedGemDecorator(newBlueGemDecorator(newShoeEquip())));

System.out.println("攻击力  : "+ equip.caculateAttack());

System.out.println("描述 :"+ equip.description());

System.out.println("-------");

// 一个镶嵌1颗红宝石,1颗蓝宝石的武器

System.out.println(" 一个镶嵌1颗红宝石,1颗蓝宝石,1颗黄宝石的武器");

equip = newRedGemDecorator(newBlueGemDecorator(newYellowGemDecorator(newArmEquip())));

System.out.println("攻击力  : "+ equip.caculateAttack());

System.out.println("描述 :"+ equip.description());

System.out.println("-------");

}

}

输出:

一个镶嵌2颗红宝石,1颗蓝宝石的靴子

攻击力  : 40

描述 :圣战靴子+ 蓝宝石+ 红宝石+ 红宝石

-------

一个镶嵌1颗红宝石,1颗蓝宝石,1颗黄宝石的武器

攻击力  : 50

描述 :屠龙刀+ 黄宝石+ 蓝宝石+ 红宝石

-------

赞不赞,要是需求随便多几个装备,几种宝石,我们随随便便就可以加上,然后开开心心下班。

好了,恭喜你,你又学会了一个设计模式,装饰者模式。

现在根据例子对定义的理解,不用我多说吧。

Java的API中也有装饰者模式的身影,如果你初学Java,一定记得Java里面的各种流,很痛苦吧,但是当你明

白你们的设计之后就会感觉清晰很多。

0818b9ca8b590ca3270a3433284dd417.png

把InputStream看作我们的IEquip,把FilterInputStream看作我们的IEquipDecorator,是不是和我们的设计几乎一样

其实就是传递对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值