第九篇:裝飾者模式

今天我們來談談裝飾者模式! 說起這個模式,相信大家都有過接觸,java的IO體系總用過吧,IO體系中各種流都可以見到裝飾者的影子,比如BufferedReader和Reader,通過向BufferedReader的構造函數中傳入一個Reader,這個Reader就具備了緩衝的能力!

再舉個例子,比如你是一個光溜溜的人, 給你套一件麻布衣服,你就成了一個平民,擁有了外出打醬油的能力(不穿衣服你敢出去???) , 再在你麻布衣服上套一層布甲,你成了一個低級士兵,擁有了戰鬥的能力!  如果再在布甲上面套一層蝙蝠戰甲,你就有了蝙蝠俠戰鬥的能力,有一天,你覺得蝙蝠俠還不夠厲害,沒關係,脫掉蝙蝠戰甲,套上一層鋼鐵戰甲,恭喜你,你成了鋼鐵俠!


沒錯,裝飾者模式就是這樣,一層套一層,每一個對象都可以用來裝飾別的對象,也可以被更高級的對象裝飾, OK,我們畫個圖來看看吧!



上面的圖很簡單明瞭,因此,我們現在要來思考怎麼樣來實現這麼一個模型呢?要讓一個類既能成爲裝飾者,又能成爲被裝飾者呢?裝飾者和被裝飾者看上去是想同的,只不過多了某種能力而已...如果是這樣的話,好像如果它們擁有同一個類型的話就可以做到吧!

Ok,我們來寫代碼吧!

/**一個抽象人類*/
public abstract class AbstractPerson {
	//每個人默認都是光溜溜的
	protected String desc = "光溜溜" ; 
	//此方法沒什麼作用,只是爲了打印測試效果
	public String getDesc(){
		return desc;
	}
	/**每個人都有戰鬥能力*/
	abstract int combatCount();
}

/**一個光溜溜的男人,默認只有10點戰鬥力*/
class Man extends AbstractPerson{
	@Override
	int combatCount() {
		return 10;
	}
}


/**一個抽象裝飾者類*/
abstract class abstractDecorate extends AbstractPerson{
	//所有裝飾者必須持有被裝飾者的引用!
	protected AbstractPerson abstractPerson;
	
	public abstractDecorate( AbstractPerson abstractPerson) {
		this.abstractPerson = abstractPerson;
	}
	
	//覆蓋描述方法,簡單的打印一下!
	@Override
	public String getDesc() {
		return  this.abstractPerson.getDesc()+",套了一層["+this.desc+"],戰鬥力提示至["+this.combatCount()+"]";
	}
}

接下來創造4個裝飾者;

/**一件麻布衣服*/
class Clothes extends abstractDecorate{
	
	public Clothes(AbstractPerson abstractPerson) {
		super(abstractPerson);
		this.desc = "麻布衣服";
	}
	@Override
	int combatCount() {//穿上了麻布衣服,增加30點攻擊力
		return this.abstractPerson.combatCount()+30;
	}
}

/**一件布甲*/
class Corselet extends abstractDecorate{
	
	public Corselet(AbstractPerson abstractPerson) {
		super(abstractPerson);
		this.desc = "布甲";
	}
	@Override
	int combatCount() {//穿上了布甲,增加100點攻擊力
		return this.abstractPerson.combatCount()+100;
	}
}

/**一件蝙蝠俠戰甲*/
class BatCorselet extends abstractDecorate{
	
	public BatCorselet(AbstractPerson abstractPerson) {
		super(abstractPerson);
		this.desc = "蝙蝠俠戰甲";
	}
	@Override
	int combatCount() {//穿上了蝙蝠俠戰甲,增加1000點攻擊力
		return this.abstractPerson.combatCount()+10000;
	}
}

/**一件超級鋼鐵俠智能戰甲*/
class SteelCorselet extends abstractDecorate{
	
	public SteelCorselet(AbstractPerson abstractPerson) {
		super(abstractPerson);
		this.desc = "超級鋼鐵俠智能戰甲";
	}
	@Override
	int combatCount() {//穿上了蝙蝠俠戰甲,增加10000000點攻擊力
		return this.abstractPerson.combatCount()+10000000;
	}
}


我們來測試一下!

public class Test {
	public static void main(String[] args) {
		AbstractPerson person = new Man();
		person.desc="一個男人";
		person = new Clothes(person);
		person = new Corselet(person);
		person = new BatCorselet(person);
		System.out.println(person.getDesc());
	}
}
輸出************************************************

一個男人,套了一層[麻布衣服],戰鬥力提示至[40],套了一層[布甲],戰鬥力提示至[140],套了一層[蝙蝠俠戰甲],戰鬥力提示至[10140]

*****************************************************
如果我們想擁有鋼鐵俠的飛行能力怎麼辦?很簡單嘛!將person = new BatCorselet(person)換成person = new SteelCorselet(person)不就可以了嘛!

在上門代碼中,Man是一個最基本的類,它是一個光溜溜的人,沒有任何能力,我們通過創造多個裝飾者,並挨個將被裝飾者包裝一遍,使其提高了戰鬥力,擁有了各種能力,比如套上蝙蝠俠戰甲,它就有了開蝙蝠戰車的能力(我代碼中沒寫這些) ,而換成鋼鐵俠戰甲,則擁有了飛行能力...

通過上面的代碼,我們基本可以得出裝飾者模式的定義:那就是能在運行時,動態給某個對象增加新的功能行爲,裝飾者模式底層就是用組合,裝飾者組合被裝飾者!



發佈了48 篇原創文章 · 獲贊 5 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章