转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24269409
今天继续设计模式之旅,给大家带来装饰者模式,国际惯例,先看定义。
装饰者模式:若要扩展功能,装饰者提供了比集成更有弹性的替代方案,动态地将责任附加到对象上。
先简单描述下装饰者模式发挥作用的地方,当我们设计好了一个类,我们需要给这个类添加一些辅助的功能,并且不希望改变这个类的代码,这时候就是装饰者模式大展雄威的时候了。这里还体现了一个原则:类应该对扩展开放,对修改关闭。
下面进入正题,今天在那看电影,忽然想起年轻时在游戏场上的血雨腥风啊,哈哈,下面以游戏为背景介绍装饰者模式。玩过游戏的兄弟应该都知道,游戏里面每个角色有武器、鞋子、护腕、戒指、还有各种红宝石、蓝宝石、黄宝石等等。
下面需求开始:设计游戏的装备系统,基本要求,要可以计算出每种装备在镶嵌了各种宝石后的攻击力和描述:
具体需求:
1、武器(攻击力20) 、戒指(攻击力5)、护腕(攻击力5)、鞋子(攻击力5)
2、蓝宝石(攻击力5/颗)、黄宝石(攻击力10/颗)、红宝石(攻击力15/颗)
3、每个装备可以随意镶嵌3颗
好了,需求介绍完毕,当然了,不要吐槽我的设计,尼玛鞋子哪来的攻击力,关键时刻也是可以砸人的嘛。下面开始初步的设想,出于多年面向对象的经验,我们可能会这么设计:
如果你这么设计了,我靠,就这么点需求你写了几百个类,随便添加两个宝石,哈哈,指数增长听过么,准备加班吧。
可能你还会这么设计:写一个超类,然后里面各种set宝石,然后在计算攻击力的地方,使劲的If有哪几种宝石,恭喜你,代码量不是很大,但是随便添加个武器,你得又多写多少个IF呢。
上面叙述了一些可能性的设计,都不是很好,下面看看如何将装饰者模式融入:
首先是装备的超类
package com.zhy.pattern.decorator;
/**
* 装备的接口
*
* @author zhy
*
*/
public interface IEquip
{
/**
* 计算攻击力
*
* @return
*/
public int caculateAttack();
/**
* 装备的描述
*
* @return
*/
public String description();
}
然后分别是武器、戒指、护腕、鞋子
package com.zhy.pattern.decorator;
/**
* 武器
* 攻击力20
* @author zhy
*
*/
public class ArmEquip implements IEquip
{
@Override
public int caculateAttack()
{
return 20;
}
@Override
public String description()
{
return "屠龙刀";
}
}
package com.zhy.pattern.decorator;
/**
* 戒指
* 攻击力 5
* @author zhy
*
*/
public class RingEquip implements IEquip
{
@Override
public int caculateAttack()
{
return 5;
}
@Override
public String description()
{
return "圣战戒指";
}
}
package com.zhy.pattern.decorator;
/**
* 护腕
* 攻击力 5
* @author zhy
*
*/
public class WristEquip implements IEquip
{
@Override
public int caculateAttack()
{
return 5;
}
@Override
public String description()
{
return "圣战护腕";
}
}
package com.zhy.pattern.decorator;
/**
* 鞋子
* 攻击力 5
* @author zhy
*
*/
public class ShoeEquip implements IEquip
{
@Override
public int caculateAttack()
{
return 5;
}
@Override
public String description()
{
return "圣战靴子";
}
}
接下来当然是装饰品,宝石了,首先超类
package com.zhy.pattern.decorator;
/**
* 装饰品的接口
* @author zhy
*
*/
public interface IEquipDecorator extends IEquip
{
}
下来蓝宝石、黄宝石、红宝石
package com.zhy.pattern.decorator;
/**
* 蓝宝石装饰品
* 每颗攻击力+5
* @author zhy
*
*/
public class BlueGemDecorator implements IEquipDecorator
{
/**
* 每个装饰品维护一个装备
*/
private IEquip equip;
public BlueGemDecorator(IEquip equip)
{
this.equip = equip;
}
@Override
public int caculateAttack()
{
return 5 + equip.caculateAttack();
}
@Override
public String description()
{
return equip.description() + "+ 蓝宝石";
}
}
package com.zhy.pattern.decorator;
/**
* 黄宝石装饰品
* 每颗攻击力+10
* @author zhy
*
*/
public class YellowGemDecorator implements IEquipDecorator
{
/**
* 每个装饰品维护一个装备
*/
private IEquip equip;
public YellowGemDecorator(IEquip equip)
{
this.equip = equip;
}
@Override
public int caculateAttack()
{
return 10 + equip.caculateAttack();
}
@Override
public String description()
{
return equip.description() + "+ 黄宝石";
}
}
package com.zhy.pattern.decorator;
/**
* 红宝石装饰品 每颗攻击力+15
*
* @author zhy
*
*/
public class RedGemDecorator implements IEquipDecorator
{
/**
* 每个装饰品维护一个装备
*/
private IEquip equip;
public RedGemDecorator(IEquip equip)
{
this.equip = equip;
}
@Override
public int caculateAttack()
{
return 15 + equip.caculateAttack();
}
@Override
public String description()
{
return equip.description() + "+ 红宝石";
}
}
好了,到此结束,我们已经实现了需求的功能了,是不是每个类都很清晰加简单,下面看测试:
package com.zhy.pattern.decorator;
public class Test
{
public static void main(String[] args)
{
// 一个镶嵌2颗红宝石,1颗蓝宝石的靴子
System.out.println(" 一个镶嵌2颗红宝石,1颗蓝宝石的靴子");
IEquip equip = new RedGemDecorator(new RedGemDecorator(new BlueGemDecorator(new ShoeEquip())));
System.out.println("攻击力 : " + equip.caculateAttack());
System.out.println("描述 :" + equip.description());
System.out.println("-------");
// 一个镶嵌1颗红宝石,1颗蓝宝石的武器
System.out.println(" 一个镶嵌1颗红宝石,1颗蓝宝石,1颗黄宝石的武器");
equip = new RedGemDecorator(new BlueGemDecorator(new YellowGemDecorator(new ArmEquip())));
System.out.println("攻击力 : " + equip.caculateAttack());
System.out.println("描述 :" + equip.description());
System.out.println("-------");
}
}
输出:
一个镶嵌2颗红宝石,1颗蓝宝石的靴子
攻击力 : 40
描述 :圣战靴子+ 蓝宝石+ 红宝石+ 红宝石
-------
一个镶嵌1颗红宝石,1颗蓝宝石,1颗黄宝石的武器
攻击力 : 50
描述 :屠龙刀+ 黄宝石+ 蓝宝石+ 红宝石
-------
赞不赞,要是需求随便多几个装备,几种宝石,我们随随便便就可以加上,然后开开心心下班。
好了,恭喜你,你又学会了一个设计模式,装饰者模式。
现在根据例子对定义的理解,不用我多说吧。
Java的API中也有装饰者模式的身影,如果你初学Java,一定记得Java里面的各种流,很痛苦吧,但是当你明
白你们的设计之后就会感觉清晰很多。
把InputStream看作我们的IEquip,把FilterInputStream看作我们的IEquipDecorator,是不是和我们的设计几乎一样~
好了,就到这里,编程也是很有乐趣的么~是吧,各位看官留个言、给个赞呗~
分享到:
相关推荐
设计模式--装饰者模式java例子
java设计模式之装饰者模式代码
Java 经典设计模式讲解以及项目实战 设计模式简介:主要介绍各种设计模式的概念和运用场景等 设计模式综合运用:主要是笔者在实际工作中运用到的一些设计模式综合运用事例的提炼 Spring设计模式简介:主要是讲述...
这个http://blog.csdn.net/dawanganban/article/details/9990405博客中java设计模式的源代码。下载前请先看《设计模式——建造者模式》一文。
设计模式,让代码更优化,拓展性更高,可读性更好,让你更好地理解设计模式
设计模式—装饰者模式
如果你想要深入透彻地理解和掌握设计模式,并期望能真正把设计模式应用到项目中去,那么这是你不可错过的一本好书。 《研磨设计模式》难度为初级到中级,适合与所有开发人员、设计人员或者即将成为开发人员的朋友。...
设计模式—装饰者模式,介绍的非常详细,讲解透彻
设计模式之建造者模式代码示例,
设计模式 - 装饰者模式
c# ,设计模式,装饰者模式,星巴兹咖啡,基本上就是head first 上的例子的C#实现,根据自己的理解,作了一点点改动,可以直接运行。
设计模式主要分为三大类: 1.创建型模式:工厂模式、抽象...4.行为型模式:模板方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式。
设计模式07-组合模式、装饰模式 设计模式09-外观模式、享元模式 设计模式10-代理模式、结构型模式大复习 设计模式11-行为模式-责任链、命令模式 设计模式12-解释器模式 设计模式13-迭代器模式 设计模式14-中介者模式...
C_设计模式(23种设计模式)C_设计模式(23种设计模式)C_设计模式(23种设计模式)C_设计模式(23种设计模式)C_设计模式(23种设计模式)C_设计模式(23种设计模式)C_设计模式(23种设计模式)C_设计模式(23种设计模式)C_设计...
设计模式 带源码设计模式 带源码设计模式 带源码设计模式 带源码设计模式 带源码设计模式 带源码设计模式 带源码
Qt设计模式之装饰者模式
章节介绍:1、爪哇语言结构性模式之变压器模式介绍 2、爪哇语言抽象工厂创立性模式介绍 3、工厂方法创立性模式介绍 4、单态创立性模式介绍 5、单态创立性模式介绍 6、观察者模式介绍7、责任链模式 8、设计模式之...
该系统是一个画图程序,我们要用设计模式的思想来设计系统结构,然后实现基本图形的绘制功能。 1.1 设计模式要求 在软件的设计中请使用到三种以上设计模式。 1.2 画图基本要求 能实现基本图形的绘制功能,包括实现...
本章可以称为“给爱用继承的人一个全新的设计眼界”。我们即将再度探讨典型...一旦你熟悉了装饰者的技巧,你将能够在不修改任何底层代码的情况下,给你的(或别人的)对象赋予新的职责。——《Head First 设计模式》
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 其实还有两类:并发型模式和线程池模式。