今天我們來談談裝飾者模式! 說起這個模式,相信大家都有過接觸,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是一個最基本的類,它是一個光溜溜的人,沒有任何能力,我們通過創造多個裝飾者,並挨個將被裝飾者包裝一遍,使其提高了戰鬥力,擁有了各種能力,比如套上蝙蝠俠戰甲,它就有了開蝙蝠戰車的能力(我代碼中沒寫這些) ,而換成鋼鐵俠戰甲,則擁有了飛行能力...
通過上面的代碼,我們基本可以得出裝飾者模式的定義:那就是能在運行時,動態給某個對象增加新的功能行爲,裝飾者模式底層就是用組合,裝飾者組合被裝飾者!