本篇是設計模式系列的第四篇,雖然以前也寫過相應的文章,可是由於種種緣由後來斷掉了,並且發現以前寫的內容也很渣,不夠系統。
因此如今打算重寫,加上距離如今也有一段時間了,也算是本身的一個回顧吧!
設計模式不是語法,是一種巧妙的寫法,能把程序變的更加靈活。架構模式比設計模式大,架構模式是戰略,而設計模式是戰術。
設計模式分爲3大類型:建立型,行爲型,結構型,總共有23種。
裝飾模式(Decorator)指的是在沒必要改變類文件和使用繼承的狀況下,動態地擴展一個對象的功能。它是經過建立一個包裝對象,也就是裝飾來包裹真實的對象。
這種模式建立了一個裝飾類,用來包裝原有的類,並在保持類方法簽名完整性的前提下,提供了額外的功能。
公司接到一個任務,須要爲某平臺開發一個搭配不一樣服飾的小項目,好比相似QQ、網絡遊戲或論壇都有的Avatar系統(爲了簡化代碼,直接使用控制檯模擬)。
通過公司的慎重討論(實際就幾秒鐘),開發這一個項目的重任,又當仁不讓的被產品經理交給了我,我:臉上笑嘻嘻,內心MMP。發一下下的小牢騷,不過仍是抓緊幹活。
思索一下,該系統要爲不一樣的人進行裝扮,因此定義一我的的類,不用每次裝扮其餘人時修改該類的代碼。
而後人身上要有不少的服飾,好比:大T恤、垮褲、鞋子等等,而後穿上以後,須要展現出來。因此這裏的話,能夠抽象出一個服飾的基類,而後各個具體的服飾都繼承該基類便可。
/**
* @author: LKP
* @date: 2019/2/16
*/
public class Person {
private String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
public void show() {
System.out.println("裝扮者:" + name);
}
}複製代碼
/**
* @author: LKP
* @date: 2019/2/16
*/
public class Finery extends Person {
protected Person component;
/**
* 打扮
* @param component
*/
public void decorate(Person component){
this.component = component;
}
@Override
public void show() {
if(null != component){
component.show();
}
}
}複製代碼
/**
* @author: LKP
* @date: 2019/2/16
*/
public class TShirts extends Finery {
@Override
public void show() {
System.out.println("大T恤");
}
}
class BigTrouser extends Finery {
@Override
public void show() {
System.out.println("垮褲");
}
}
class Sneakers extends Finery{
@Override
public void show() {
System.out.println("破球鞋");
}
}
class LeatherShoes extends Finery{
@Override
public void show() {
System.out.println("皮鞋");
}
}
class Tie extends Finery{
@Override
public void show() {
System.out.println("領帶");
}
}
class Suit extends Finery{
@Override
public void show() {
System.out.println("西裝");
}
}複製代碼
這裏內部類,只是爲了較少代碼量,實際開發中可不要偷懶,按實際來建立。
/**
* @author: LKP
* @date: 2019/2/16
*/
public class Main {
public static void main(String[] args) {
Person person = new Person("孤獨鍵客");
System.out.println("第一種裝扮:");
Finery tShirts = new TShirts();
Finery bigTrouser = new BigTrouser();
Finery sneakers = new Sneakers();
tShirts.show();
bigTrouser.show();
sneakers.show();
person.show();
System.out.println("\n第二種裝扮:");
Finery suit = new Suit();
Finery tie = new Tie();
Finery leatherShoes = new LeatherShoes();
suit.show();
tie.show();
leatherShoes.show();
person.show();
}
}複製代碼
搞定收工,審視一下,自我感受還算不錯,若是新裝扮只需改變一下調用順序便可,若是又新人物,只需從新new一個Person類就能夠了。
接下里將項目提交上傳,而後告訴leader一聲,over,離下班時間還早,好像還能夠作點其餘的事情~。
正當你準備打開去幹點其餘事情,leader回覆你了:
leader:「你仔細看看這段代碼,這樣寫意味着什麼?
你想象一下,是否是把‘大T恤’、‘垮褲’、‘破球鞋’、‘裝扮者’一個一個詞顯示出來,是否是至關於你光着身子,一個一個把這些穿上,這可有點像脫衣舞哦~」。
我:「你意思是,這些應該都在內部組裝完畢,而後在顯示出來?」。
leader:"賓果,並且還要按照正確的順序串聯起來控制,這裏有點難度,修改好以後再給我"。
這彷佛和某種設計模式有關,難道是建造者模式嗎?不對,建造者模式要求建造的過程必須是穩定的,而這個穿搭的過程是不固定的,一個有個性的人又無數種方案。
/**
* @author: LKP
* @date: 2019/2/16
*/
public class TShirts extends Finery {
@Override
public void show() {
System.out.println("大T恤");
super.show();
}
}
class BigTrouser extends Finery {
@Override
public void show() {
System.out.println("垮褲");
super.show();
}
}
class Sneakers extends Finery{
@Override
public void show() {
System.out.println("破球鞋");
super.show();
}
}
class LeatherShoes extends Finery{
@Override
public void show() {
System.out.println("皮鞋");
super.show();
}
}
class Tie extends Finery{
@Override
public void show() {
System.out.println("領帶");
super.show();
}
}
class Suit extends Finery{
@Override
public void show() {
System.out.println("西裝");
super.show();
}
}複製代碼
/**
* @author: LKP
* @date: 2019/2/16
*/
public class Main {
public static void main(String[] args) {
Person person = new Person("孤獨鍵客");
System.out.println("第一種裝扮:");
Sneakers sneakers = new Sneakers();
BigTrouser bigTrouser = new BigTrouser();
TShirts tShirts = new TShirts();
sneakers.decorate(person);
bigTrouser.decorate(sneakers);
tShirts.decorate(bigTrouser);
tShirts.show();
System.out.println("第二種裝扮:");
LeatherShoes leatherShoes = new LeatherShoes();
Tie tie = new Tie();
Suit suit = new Suit();
leatherShoes.decorate(person);
tie.decorate(leatherShoes);
suit.decorate(tie);
suit.show();
}
}複製代碼
光着膀子、打着領帶、下身垮褲、腳上皮鞋,絕對的極具個性。
主要解決:通常的,咱們爲了擴展一個類常用繼承方式實現,因爲繼承爲類引入靜態特徵,而且隨着擴展功能的增多,子類會很膨脹。
如何解決:將具體功能職責劃分,同時繼承裝飾者模式。
關鍵代碼: 一、Component 類充當抽象角色,不該該具體實現。 二、修飾類引用和繼承 Component 類,具體擴展類重寫父類方法。
應用實例: 一、孫悟空有 72 變,當他變成"廟宇"後,他的根本仍是一隻猴子,可是他又有了廟宇的功能。 二、不論一幅畫有沒有畫框均可以掛在牆上,可是一般都是有畫框的,而且其實是畫框被掛在牆上。在掛在牆上以前,畫能夠被蒙上玻璃,裝到框子裏;這時畫、玻璃和畫框造成了一個物體。
優勢:裝飾類和被裝飾類能夠獨立發展,不會相互耦合,裝飾模式是繼承的一個替代模式,裝飾模式能夠動態擴展一個實現類的功能。
使用場景: 一、擴展一個類的功能。 二、動態增長功能,動態撤銷。
歡迎關注個人公衆號「程序員的成長之路」,閱讀更多精彩!