在電視劇《相愛十年》中,主角肖然把出現(xiàn)了品控問題的安爾雅肥皂換了個包裝贱鄙、改了套說辭變成了全新的品牌浴雪清缤至,并成功的推銷出去了潮罪,得到了第一桶金康谆。這就說所謂的包裝,本質(zhì)上并沒有改變嫉到,但是外在表現(xiàn)形式上有了改動沃暗,給人感覺這好像是一個全新的物種一樣。
日光之下并無新事何恶,這話出自《圣經(jīng)》孽锥,講的就是這道理。
在編程領(lǐng)域同樣會存在這種包裝的需求细层,比如我們需要更改某個類的行為惜辑,但它是 final 類型的,不能繼承疫赎∈⒊牛或者是干脆就不想繼承,想通過組合的方式去包裝它捧搞,以達(dá)到這種修改對象行為的目的抵卫。
比如 JavaWeb 中的 HttpServletRequestWrapper 類就是一個典型的包裝器類,它就是應(yīng)用了包裝器設(shè)計模式的思想胎撇。這個類持有了原有的 request 對象介粘,實現(xiàn)了 ServletRequest 接口,重寫了它的所有方法创坞,并提供了針對 HTTP 協(xié)議的個性化功能碗短。
該設(shè)計模式中有幾個角色
學(xué)習(xí)啟示:學(xué)習(xí)設(shè)計模式的過程中,搞清楚這個模式里面有幾個角色题涨,也就是有幾個對象偎谁,理順?biāo)麄兊年P(guān)系,也就理解了這個設(shè)計模式纲堵。
在包裝器模式中從根本上來說巡雨,就只有被包裝對象和包裝對象。他們之間是一種組合關(guān)系席函,包裝對象內(nèi)部持有了被包裝對象铐望,并提供了一些被包裝對象所沒有的擴(kuò)展行為。多出來或者改動的行為就是包裝茂附!
如何實現(xiàn)包裝器模式/裝飾器模式
「英文時間」:decorator n. 裝飾器
「英文時間」:wrapper n. 包裝材料
包裝器設(shè)計模式的核心就是正蛙,通過組合和繼承同一個接口的方式,不需要更改的行為就用默認(rèn)實現(xiàn)营曼,需要更改的就自定義修改乒验。
下面還是以一個上面安爾雅和浴雪清肥皂的例子來講解具體的代碼如何寫,UML 類圖和具體操作步驟如下:
- 第一步:定義包裝類和被包裝類共同的接口
- 第二步:定義被包裝類蒂阱,并實現(xiàn)接口的方法
- 第三步:定義包裝類锻全,并通過構(gòu)造函數(shù)接收被包裝類對象狂塘,將其作為內(nèi)部屬性持有。然后按照實際選擇修改或者新增行為鳄厌!
共同的接口:肥皂
//肥皂的接口
public interface Soap {
void wash();
void name();
}
被包裝類:安爾雅肥皂
//
class AnErYa implements Soap{
@Override
public void wash() {
System.out.println("肥皂洗澡更干凈");
}
@Override
public void name() {
System.out.println("安爾雅");
}
}
包裝類:浴雪清肥皂
class YuXueQing implements Soap{
private Soap sopa;//持有被包裝類的引用
public YuXueQing(Soap s) {
this.sopa = s;//獲取被包裝類的引用
}
//修改被包裝對象的行為
@Override
public void name() {
System.out.println("浴雪清");
}
//定義默認(rèn)實現(xiàn)
@Override
public void wash() {
this.sopa.wash();
}
//浴雪清新增行為
public void medicine(){
System.out.println("中藥成分");
}
}
測試代碼:
public static void main(String[] args) {
Soap s1 = new AnErYa();
Soap s2 = new YuXueQing(s1);
s2.wash();
s2.name();
YuXueQing y = (YuXueQing) s2;
y.medicine();
}