本文已經收錄到Github倉庫,該倉庫包含計算機基礎、Java基礎、多執行緒、JVM、資料庫、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分散式、微服務、設計模式、架構、校招社招分享等核心知識點,歡迎star~
Github地址:https://github.com/Tyson0314/...
裝飾者模式(decorator pattern):動態地將責任附加到物件上, 若要擴充套件功能, 裝飾者提供了比繼承更有彈性的替代方案。
裝飾模式以對客戶端透明的方式擴充物件的功能,客戶端並不會覺得物件在裝飾前和裝飾後有什麼不同。裝飾模式可以在不創造更多子類的情況下,將物件的功能加以擴充套件。
比如設定FileInputStream,先用BufferedInputStream裝飾它,再用自己寫的LowerCaseInputStream過濾器去裝飾它。
InputStream in = new LowerCaseInputStream(new BufferedInputStream(new FileInputStream("test.txt")));
在裝飾模式中的角色有:
- 抽象元件(Component)角色:給出一個抽象介面,以規範準備接收附加責任的物件。
- 具體元件(ConcreteComponent)角色:定義一個將要接收附加責任的類。
- 抽象裝飾(Decorator)角色:持有一個元件(Component)物件的例項,並定義一個與抽象元件介面一致的介面。
- 具體裝飾(ConcreteDecorator)角色:負責給構件物件“貼上”附加的責任。
程式碼例項
LOL、王者榮耀等類Dota遊戲中,每次英雄升級都會附加一個額外技能點學習技能,這個就類似裝飾模式為已有類動態附加額外的功能。
具體的英雄就是ConcreteComponent,技能欄就是裝飾器Decorator,每個技能就是ConcreteDecorator。
新建一個介面:
public interface Hero {
//學習技能
void learnSkills();
}
建立介面的實現類(具體英雄盲僧):
//ConcreteComponent 具體英雄盲僧
public class BlindMonk implements Hero {
private String name;
public BlindMonk(String name) {
this.name = name;
}
@Override
public void learnSkills() {
System.out.println(name + "學習了以上技能!");
}
}
裝飾角色:
//Decorator 技能欄
public abstract class Skills implements Hero {
//持有一個英雄物件介面
private Hero hero;
public Skills(Hero hero) {
this.hero = hero;
}
@Override
public void learnSkills() {
if(hero != null)
hero.learnSkills();
}
}
具體裝飾角色:
//ConreteDecorator 技能:Q
public class Skill_Q extends Skills{
private String skillName;
public Skill_Q(Hero hero,String skillName) {
super(hero);
this.skillName = skillName;
}
@Override
public void learnSkills() {
System.out.println("學習了技能Q:" +skillName);
super.learnSkills();
}
}
//ConreteDecorator 技能:W
public class Skill_W extends Skills{
private String skillName;
public Skill_W(Hero hero,String skillName) {
super(hero);
this.skillName = skillName;
}
@Override
public void learnSkills() {
System.out.println("學習了技能W:" + skillName);
super.learnSkills();
}
}
//ConreteDecorator 技能:E
public class Skill_E extends Skills{
private String skillName;
public Skill_E(Hero hero,String skillName) {
super(hero);
this.skillName = skillName;
}
@Override
public void learnSkills() {
System.out.println("學習了技能E:"+skillName);
super.learnSkills();
}
}
//ConreteDecorator 技能:R
public class Skill_R extends Skills{
private String skillName;
public Skill_R(Hero hero,String skillName) {
super(hero);
this.skillName = skillName;
}
@Override
public void learnSkills() {
System.out.println("學習了技能R:" +skillName );
super.learnSkills();
}
}
客戶端:
//客戶端:召喚師
public class Player {
public static void main(String[] args) {
//選擇英雄
Hero hero = new BlindMonk("李青");
Skills skills = new Skills(hero);
Skills r = new Skill_R(skills,"猛龍擺尾");
Skills e = new Skill_E(r,"天雷破/摧筋斷骨");
Skills w = new Skill_W(e,"金鐘罩/鐵布衫");
Skills q = new Skill_Q(w,"天音波/迴音擊");
//學習技能
q.learnSkills();
}
}
輸出:
學習了技能Q:天音波/迴音擊
學習了技能W:金鐘罩/鐵布衫
學習了技能E:天雷破/摧筋斷骨
學習了技能R:猛龍擺尾
李青學習了以上技能!
最後給大家分享一個Github倉庫,上面有大彬整理的300多本經典的計算機書籍PDF,包括C語言、C++、Java、Python、前端、資料庫、作業系統、計算機網路、資料結構和演算法、機器學習、程式設計人生等,可以star一下,下次找書直接在上面搜尋,倉庫持續更新中~
Github地址:https://github.com/Tyson0314/...