設計模式 裝飾者模式 帶你重回傳奇世界

轉載請標明出處:http://blog.csdn.net/lmj623565791/article/details/24269409java

今天繼續設計模式之旅,給你們帶來裝飾者模式,國際慣例,先看定義。編程

裝飾者模式:若要擴展功能,裝飾者提供了比集成更有彈性的替代方案,動態地將責任附加到對象上。設計模式

先簡單描述下裝飾者模式發揮做用的地方,當咱們設計好了一個類,咱們須要給這個類添加一些輔助的功能,而且不但願改變這個類的代碼,這時候就是裝飾者模式大展雄威的時候了。這裏還體現了一個原則:類應該對擴展開放,對修改關閉。ide

下面進入正題,今天在那看電影,突然想起年輕時在遊戲場上的血雨腥風啊,哈哈,下面以遊戲爲背景介紹裝飾者模式。玩過遊戲的兄弟應該都知道,遊戲裏面每一個角色有武器、鞋子、護腕、戒指、還有各類紅寶石、藍寶石、黃寶石等等。測試

下面需求開始:設計遊戲的裝備系統,基本要求,要能夠計算出每種裝備在鑲嵌了各類寶石後的攻擊力和描述:ui

具體需求:this

一、武器(攻擊力20) 、戒指(攻擊力5)、護腕(攻擊力5)、鞋子(攻擊力5)url

二、藍寶石(攻擊力5/顆)、黃寶石(攻擊力10/顆)、紅寶石(攻擊力15/顆)spa

三、每一個裝備能夠隨意鑲嵌3顆.net


好了,需求介紹完畢,固然了,不要吐槽個人設計,尼瑪鞋子哪來的攻擊力,關鍵時刻也是能夠砸人的嘛。下面開始初步的設想,出於多年面向對象的經驗,咱們可能會這麼設計:

若是你這麼設計了,我靠,就這麼點需求你寫了幾百個類,隨便添加兩個寶石,哈哈,指數增加聽過麼,準備加班吧。

可能你還會這麼設計:寫一個超類,而後裏面各類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,是否是和咱們的設計幾乎同樣~


好了,就到這裏,編程也是頗有樂趣的麼~是吧,各位看官留個言、給個讚唄~



源碼點擊下載

相關文章
相關標籤/搜索