**小Y:**Hello,你們好,歡迎來到魂鬥羅.歸來的世界,下面讓小Y帶領你們一塊兒去採訪一下叼煙大漢比爾·雷澤,讓你們更加理解這個粗狂的戰鬥漢子。Let's go。!ide
**小Y:**你最喜歡幹什麼?學習
**比爾·雷澤:**最喜歡衝關打爆大機。this
**小Y:**比爾,你想對觀衆說些什麼?spa
**比爾·雷澤:**想挑戰我,隨時奉陪!一顆不夠,給你來三顆!設計
小Y:......3d
比爾·雷澤做爲魂鬥羅這麼經典的人物,原來也是一個粗狂耿直boy呀。爲了保存住他的光輝形象和讓你們更加了解他,小Y決定把比爾·雷澤的攻擊技能裝飾一番介紹給你們認識。代理
**比爾·雷澤在戰場上在戰場上基本上用散彈槍能夠橫掃小兵,可是遇到一些特殊的狀況仍是須要經過G5手雷、集速手雷、爆破飛彈等技能來進行輔助。**那麼如何設置這些技能才合適呢?簡單,小Y腦海中立馬閃過幾種方案:調試
(1)採用繼承的方式,設定一個比爾·雷澤類,有多少個技能就寫多少個子類來繼承這個比爾·雷澤類。 code
看完這個圖,小Y本身都蒙逼了,每增長一個技能能夠組合出N個子類,這只是一個比爾·雷澤,再來個艾薇、寒鋒什麼的,那不就要加到天荒地老?cdn
(2)直接抽象一個角色類,裏面包含了每一個角色的技能。
這樣子有多少個角色就增長多少個子類就能夠了,不用根據技能增長類,避免形成子類爆炸,可是,每一個角色的技能是能夠疊加使用的,角色越多或者技能疊加種類越多,那麼就要在超類增長越多的方法,並且直接修改超類不符合開閉原則(超類對擴展開放,對修改關閉)。
(3)今天的主題— 裝飾模式。
裝飾模式(Decorator Pattern)是一種比較常見的模式,動態地給一個對象添加一些額外的職責(就增長功能來講,裝飾模式相比生成子類更爲靈活)。
Component抽象構件
Component是一個接口或者是抽象類,就是定義咱們最核心的對象,也就是最原始的對象(在裝飾模式中,必然有一個最基本、最核心、最原始的接口或抽象類充當Component抽象構件) 。
ConcreteState具體狀態角色
ConcreteComponent 具體構件,是Component的具體實現,要裝飾的就是它 。
Decorator裝飾角色
通常是一個抽象類,實現Component接口或者抽象方法,它裏面可不必定有抽象的方法呀,在它的屬性裏必然有一個private變量指向Component抽象構件(若是具體裝飾角色只有一個,這個能夠省略)。
ConcreteDecorator具體裝飾角色
把你最核心的、最原始的、最基本的東西裝飾成想要的東西。
(1)裝飾模式實現角色裝飾UML圖
①抽象角色類
public abstract class Character {
public abstract void attack();
}
複製代碼
②實現角色比爾·雷澤(對它進行裝飾)
public class BillRizer extends Character {
@Override
public void attack() {
//角色最基本的技能
System.out.print("散彈槍進行掃射!");
}
}
複製代碼
③技能裝飾抽象類
public abstract class SkillDecorator extends Character{
private Character character;
public SkillDecorator(Character character) {
this.character = character;
}
@Override
public void attack() {
this.character.attack();
}
}
複製代碼
④G5手雷技能
public class G5GrenadeDecorator extends SkillDecorator {
public G5GrenadeDecorator(Character character) {
super(character);
}
@Override
public void attack() {
super.attack();
System.out.print("G5手雷輔助攻擊!");
}
}
複製代碼
⑤集速手雷技能
public class SetspeedDecorator extends SkillDecorator {
public SetspeedDecorator(Character character) {
super(character);
}
@Override
public void attack() {
super.attack();
System.out.print("集速手雷輔助!");
}
}
複製代碼
⑥爆破飛彈技能
public class ExplosiveMissileDecorator extends SkillDecorator {
public ExplosiveMissileDecorator(Character character) {
super(character);
}
@Override
public void attack() {
super.attack();
System.out.print("爆破飛彈輔助!");
}
}
複製代碼
⑦客戶端
public class Client {
public static void main(String[] args){
//須要裝飾的BillRizer
BillRizer billRizer=new BillRizer();
//使用G5手雷輔助
G5GrenadeDecorator g5GrenadeDecorator=new G5GrenadeDecorator(billRizer);
g5GrenadeDecorator.attack();
//使用G5手雷+集速手雷+爆破飛彈輔助
SetspeedDecorator setspeedDecorator=new SetspeedDecorator(g5GrenadeDecorator);
ExplosiveMissileDecorator explosiveMissileDecorator=new ExplosiveMissileDecorator(setspeedDecorator);
explosiveMissileDecorator.attack();
}
}
複製代碼
輸出結果:
①散彈槍進行掃射!G5手雷輔助攻擊!
②散彈槍進行掃射!G5手雷輔助攻擊!集速手雷輔助!爆破飛彈輔助!
複製代碼
優勢:
①裝飾類和被裝飾類能夠獨立發展,而不會相互耦合。Component類無須知道Decorator類,而Decorator也不用知道具體的構件,用戶能夠根據須要增長新的具體構件類和具體裝飾類,在使用時再對其進行組合,原有代碼無須改變,符合「開閉原則」。 ②裝飾模式是繼承關係的一個替代方案。裝飾模式與繼承關係的目的都是要擴展對象的功能,可是裝飾模式能夠提供比繼承更多的靈活性。 ③經過使用不一樣的具體裝飾類以及這些裝飾類的排列組合,能夠創造出不少不一樣行爲的組合。
缺點:
①這種比繼承更加靈活機動的特性,也同時意味着裝飾模式比繼承更加易於出錯,排錯也很困難,對於屢次裝飾的對象,調試時尋找錯誤可能須要逐級排查,較爲煩瑣。 ②使用裝飾模式進行系統設計時將產生不少小對象,這些裝飾類和小對象的產生將增長系統的複雜度,加大學習與理解的難度。