裝飾器模式的定義:動態地給乙個物件新增一些額外的職責。就增加功能來說,裝飾器模式比生成子類更為靈活。
我們先來看一下裝飾器模式的結構圖:
裝飾器模式遵守的程式設計原則之一就是「開放-關閉原則」,倘若concretecomponent的operation方法是乙個很複雜的且經常變更的方法,我們不可能在每次變更的時候都去更改這個operation方法,在裡面寫一大堆if...else...,這樣將來兼職是不堪入目。於是我們想通過外部的其他類(裝飾器類)來透明的為concretecomponent的operation方法擴充套件功能。我們要給concretecomponent這個物件增加功能,但是不能讓這個物件知道,也就是不能去改動這個物件。
接下來我們來看下裝飾器模式的**(我們假設的應用場景是算工資,假設 應發工資=基本工資-剋扣工資+獎金):
publicclass
salary:isalary
}
publicabstract
abstractsalary:isalary
public
double calsalary(string
username)
}
publicclass
takeoffsalary:abstractsalary
public
double calsalary(string
username)
}
public最後我們再來看看客戶端是怎麼用的:class
bonussalary:abstractsalary
public
double calsalary(string
username)
}
public看過前面的**,應該可以看出這裡的呼叫其實是遞迴呼叫,從 bonussalary.calsalary 到 takeoffsalary.calsalary 最後到 salary.calsalary 然後一層層返回,最終算出應發工資。所以這裡的裝飾是有順序的,但最好的裝飾器模式是各裝飾器之間最好相互獨立,這樣才能最靈活。class
client
}
這樣就能很靈活的給被裝飾類 salary 增加或減少裝飾器的功能了,這些功能就達到了動態組合的
乙個類的擴充套件方式,可以是繼承,也可以是物件組合。盡量使用物件組合,而不是繼承來擴充套件和復用功能。
舉個例子:物件a,實現了a1方法和a2方法。而b只想使用a的a1方法,使用繼承自然是不合適的,這裡就可以用到物件組合了。
public裝飾器模式是把被裝飾物件的一系列複雜的功能,分散到各個裝飾器中,並且做到了對被裝飾物件的完全透明化。這很容易讓人想起aop(面向切面程式設計),它們共同的思想是「在一段邏輯**不知情的情況下,在它前面或後面插入一段**邏輯,就像插入乙個橫切面一樣」。最容易理解的的「切面「就是像log和驗證這種散落在各模組中但其實又與具體業務邏輯關係不大的功能。我們如果使用裝飾器模式來實現aop思想的話,比如,購物系統裡使用者購買東西這個業務,具體的購買的業務邏輯的物件可以看作被裝飾物件,裝飾它的裝飾器有log裝飾器,和身份驗證裝飾器,把這3裝飾在一起,最終就能實現:使用者購買前先驗證身份,然後購買,購買完了再記錄購買log。而購買東西的這個物件完全不知道身份驗證和log這兩塊**是何時何地加入的。class
a
public
void
a2(){}
}public
class
b
public
void
b1(){}
}
更多關於aop的文章:spring aop詳解
輕鬆理解aop(面向切面程式設計)
專治不會看原始碼的毛病--spring原始碼解析aop篇
裝飾模式的本質:動態組合
裝飾器模式
大話設計模式 裝飾器模式 為已有功能動態地新增更多功能,當系統需要新功能,向舊的類中新增新功能,裝飾了原有類的核心職責和行為,而不改變它們 就像包裝袋一樣,有 的包裝袋包裝之前裝好東西的包裝袋 ifndef clothes h define clothes h include using names...
裝飾器模式
裝飾器設計模式 對真實物件動態的新增功能 抽象元件 author zhangjianbin public inte ce icar 俱體構件物件 真實的物件 author zhangjianbin class car implements icar 裝飾器物件 author zhangjianbin...
裝飾器模式
一 概念 裝飾模式能夠實現動態的為物件新增功能,是從乙個物件外部來給物件新增功能。通常給物件新增功能,要麼直接修改物件新增相應的功能,要麼派生對應的子類來擴充套件,抑或是使用物件組合的方式。顯然,直接修改對應的類這種方式並不可取。在物件導向的設計中,而我們也應該 盡量使用物件組合,而不是物件繼承來擴...