关闭

设计模式 装饰者模式 带你重回传奇世界

标签: 设计模式装饰者模式
17214人阅读 评论(40) 收藏 举报
分类:

转载请标明出处: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,是不是和我们的设计几乎一样~


好了,就到这里,编程也是很有乐趣的么~是吧,各位看官留个言、给个赞呗~



源码点击下载





129
1
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

JAVA设计模式初探之装饰者模式

这个模式花费了挺长时间,开始有点难理解,其实就是 定义:动态给一个对象添加一些额外的职责,就象在墙上刷油漆.使用Decorator模式相比用生成子类方式达到功能的扩充显得更为灵活。 设计初衷:通常...
  • jason0539
  • jason0539
  • 2014-04-01 09:07
  • 74762

设计模式 装饰者模式 带你重回传奇世界

今天继续设计模式之旅,给大家带来装饰者模式,国际惯例,先看定义。 装饰者模式:若要扩展功能,装饰者提供了比集成更有弹性的替代方案,动态地将责任附加到对象上。 先简单描述下装饰者模式发挥作用的地方,当我...
  • lmj623565791
  • lmj623565791
  • 2014-04-21 20:21
  • 17214

《java与设计模式》之装饰模式详解&Java IO中的装饰器模式

1 概述 在一个项目中,你会有非常多的因素考虑不到,特别是业务的变更,不时的冒出一个需求是很正常的情况。有三个继承关系的类:Father、Son、GrandSon,我们要在Son类上增强一些功能怎么办...
  • chs0113
  • chs0113
  • 2016-05-06 19:42
  • 7348

设计模式 装饰者模式 带你重回传奇世界

今天继续设计模式之旅,给大家带来装饰者模式,国际惯例,先看定义。装饰者模式:若要扩展功能,装饰者提供了比集成更有弹性的替代方案,动态地将责任附加到对象上。先简单描述下装饰者模式发挥作用的地方,当我们设...
  • m0_37651226
  • m0_37651226
  • 2017-06-22 20:41
  • 87

设计模式 装饰者模式 带你重回传奇世界

设计模式 装饰者模式
  • u013651026
  • u013651026
  • 2017-12-15 15:50
  • 27

设计模式 装饰者模式 带你重回传奇世界

今天继续设计模式之旅,给大家带来装饰者模式,国际惯例,先看定义。 装饰者模式:若要扩展功能,装饰者提供了比集成更有弹性的替代方案,动态地将责任附加到对象上。 先简单描述下装饰者模式发挥作用...
  • dzc372787439
  • dzc372787439
  • 2015-03-09 11:29
  • 405

设计模式 装饰者模式 带你重回传奇世界

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24269409 今天继续设计模式之旅,给大家带来装饰者模式,国际惯例,先看定...
  • walid1992
  • walid1992
  • 2016-05-22 08:55
  • 1035

设计模式-装饰者

  • 2015-11-07 10:44
  • 4.44MB
  • 下载

设计模式之装饰者(Decorator)

  • 2007-09-27 14:38
  • 316KB
  • 下载

c# ,设计模式,装饰者模式,星巴兹咖啡

  • 2011-01-01 00:31
  • 195KB
  • 下载
    个人资料
    • 访问:17922329次
    • 积分:51373
    • 等级:
    • 排名:第66名
    • 原创:205篇
    • 转载:0篇
    • 译文:6篇
    • 评论:15630条
    我的微信公众号
    联系方式


    QQ群:
    • 55032675
    • 423372824
    • 497438697
    • 请勿重复加群,Thx
    博客专栏
    统计