好久沒跟大家更新了,今天給大家?guī)淼氖且粋€新的設(shè)計模式——裝飾者模式。說到這個模式,剛開始接觸設(shè)計模式這個神秘東西的時候,我感覺這個模式是最簡單的,簡單到?jīng)]必要專門說明。本著不誤導(dǎo)大家的原則,我重新翻了翻書,發(fā)現(xiàn)并不是這樣,和原本的理解還是有所出入。好了進入正題,發(fā)車了。

首先我們不說什么是裝飾設(shè)計模式,因為太枯燥了。我希望大家能跟著我的思路一部一部走,讓設(shè)計模式的學(xué)習(xí)變得簡單,生動。
裝飾?字面就是裝修,美化之類的吧。比如我們要對房子進行裝修,首先我們要有一個房子(啊,對我來說好遙遠啊,先不管那么多),總之就是我們首先要有被裝飾的對象。
我們來看個簡單的例子:直播相信大家都看過吧,現(xiàn)在直播平臺這么多,當(dāng)然直播種類也是數(shù)不勝數(shù)。今天我們就以人物直播為例子,給大家講解下裝飾設(shè)計模式。
在直播間,你會發(fā)現(xiàn)彈幕中,好多人說:美女,好漂亮....,求聯(lián)系方式之類的,然而事實上真的那么漂亮嗎?錯,都是經(jīng)過裝飾的。假設(shè)現(xiàn)在我們有個直播類(OnLineShow),今天講解直播的一種:人物直播(FigureShow)。
當(dāng)然好多人都不是素顏直播的,經(jīng)過軟件的處理,然后將畫面展示在我們面前。畫面處理分好多種,有對人物面部進行處理的(FaceBeautiftyShow),有對場景進行美化的(ScenceBeautiftyShow),還有對互動進行處理的(InteractiveBeautiftyShow)。相信場景和人物美化大家都懂,那么什么是交互處理呢?比如我們在看直播的時候,有的時候會發(fā)現(xiàn)有人大笑之類的聲音,這些都是軟件處理的,而并不是觀眾的聲音。下面我們來梳理下其中的關(guān)系:

看到這個結(jié)構(gòu)不知道你有沒有什么疑問?
反正我是有,為什么負責(zé)裝飾的類(BeautiftyShow)要繼承OnLineShow?
別著急我們繼續(xù)往下走。這就是我文章開頭提到我重新看裝飾模式發(fā)現(xiàn)不同的地方。
我們先放下問題,用代碼實現(xiàn)下可以嗎?聽話。
OnLineShow (直播抽象類)
public abstract class OnLineShow {
public abstract void display();
}
FigureShow (人物直播)
public class FigureShow extends OnLineShow {
@Override
public void display() {
System.out.println("美女/帥哥 素顏直播了");
}
}
BeautiftyShow (直播美化抽象類) 負責(zé)裝飾
public abstract class BeautiftyShow extends OnLineShow{
@Override
public abstract void display();
}
FaceBeautiftyShow (美顏裝飾類)
public class FaceBeautiftyShow extends BeautiftyShow {
private OnLineShow onLineShow;
public FaceBeautiftyShow(OnLineShow onLineShow){
this.onLineShow = onLineShow;
}
@Override
public void display() {
onLineShow.display();
System.out.println("美顏了");
}
}
ScenceBeautiftyShow (場景美化裝飾類)
public class ScenceBeautiftyShow extends BeautiftyShow {
private OnLineShow onLineShow;
public ScenceBeautiftyShow(OnLineShow onLineShow) {
this.onLineShow = onLineShow;
}
@Override
public void display() {
onLineShow.display();
System.out.println("出現(xiàn)下雪的場景吧");
}
}
InteractiveBeautiftyShow (交互裝飾類)
public class InteractiveBeautiftyShow extends BeautiftyShow {
private OnLineShow onLineShow;
public InteractiveBeautiftyShow(OnLineShow onLineShow) {
this.onLineShow = onLineShow;
}
@Override
public void display() {
onLineShow.display();
System.out.println("鼓掌,尖叫聲");
}
}
最后我們看看測試類:
DecorateTest
public class DecorateTest {
public static void main(String[] args) {
OnLineShow figureShow = new FigureShow();
//我很帥,什么都不需要
figureShow.display();
//我要美顏功能
figureShow = new FaceBeautiftyShow(figureShow);
figureShow.display();
}
}
運行結(jié)果如下:
(1)我什么都不要(因為我很帥)

有人會說了,這種還用說嗎?弱智吧你。大兄弟,別著急,且聽我慢慢道來
(2)只要美顏(畢竟我好看了,人氣就來了)

好了,裝飾設(shè)計模式介紹完了。我先撤了。
細心的朋友就會說,裝完逼就想走,不行。你文章開頭的問題解決了嗎?想走?

我們言歸正傳,回到問題上來。
為什么負責(zé)裝飾的類(BeautiftyShow)要繼承被裝飾者(OnLineShow)?
按道理,不繼承也行啊。因為裝飾設(shè)計模式的精髓就是,裝飾者持有一個被裝飾者,然后進行擴展就行了啊。你故弄玄虛什么啊。
我: 行行行,你好看說什么都對。但是我很難看,而且很要面子。我想直播了,我丑,需要美顏,然后,我還要面子,所以我還需要場景美化與交互美化,不然說半天,沒點掌聲多尷尬。
你: 這可如何是好????
我:沒話說了吧。下面按照我的這種設(shè)計,就很容易實現(xiàn),看:
OnLineShow figureShow = new FigureShow();
figureShow = new FaceBeautiftyShow(figureShow);
figureShow = new InteractiveBeautiftyShow(figureShow);
figureShow = new ScenceBeautiftyShow(figureShow);
figureShow.display();
結(jié)果如下(驗證下,看對不對):

是不是很簡單。
我們負責(zé)裝飾的類(BeautiftyShow)繼承被裝飾者抽象類(OnLineShow),只是為了繼承它的類型,而不是為了具體的行為。因為具體的行為是在裝飾者的子類中實現(xiàn)的。
如果不繼承的話,我們要對內(nèi)容進行擴展,也就是所謂的連環(huán)裝飾。就顯得力不從心了。
好了,最后我們看看較為正式的定義(對面試官說有加分,顯得高大上)。
裝飾者模式——動態(tài)地將責(zé)任附加到對象上,進行擴展功能。
最后,關(guān)于大家的幾個疑問我想說一下。有人反饋說,你寫的這些例子我也懂,但是自己運用起來還是感覺有點吃力,怎么辦?
其實不用著急的,設(shè)計模式熟練運用到項目中還是有點難度的,一個是對設(shè)計模式本身知識的掌握,另一方面,是對所做業(yè)務(wù)還要有深入的了解,還是要有一定經(jīng)驗才可以。我們現(xiàn)在能做的就是慢慢積累,沒事的時候翻一翻,總有一天,你會豁然開朗,原來還可以這樣。
我是抽出周末時間更新的,如果覺得還寫得不錯,記得關(guān)注下,好持續(xù)給大家更新。如果發(fā)現(xiàn)文中的錯誤,記得給我說,免得誤導(dǎo)更多的人。多謝!下期見