裝飾者模式this
一、意圖: 動態地給一個對象添加一些額外的職責。就增長功能來講, Decorator模式相比生成子類更爲靈活。該模式以對客 戶端透明的方式擴展對象的功能。spa
二、適用環境 設計
(1)在不影響其餘對象的狀況下,以動態、透明的方式給單個對象添加職責。 3d
(2)處理那些能夠撤消的職責。 code
(3)當不能採用生成子類的方法進行擴充時。一種狀況是,可能有大量獨立的擴展,爲支持每一種組合將產生大量的 子類,使得子類數目呈爆炸性增加。另外一種狀況多是由於類定義被隱藏,或類定義不能用於生成子類。orm
三、參與者對象
1.Component(被裝飾對象的基類)blog
定義一個對象接口,能夠給這些對象動態地添加職責。繼承
2.ConcreteComponent(具體被裝飾對象)接口
定義一個對象,能夠給這個對象添加一些職責。
3.Decorator(裝飾者抽象類)
維持一個指向Component實例的引用,並定義一個與Component接口一致的接口。
4.ConcreteDecorator(具體裝飾者)
具體的裝飾對象,給內部持有的具體被裝飾對象,增長具體的職責。
四、類圖
五、涉及角色
(1)抽象組件:定義一個抽象接口,來規範準備附加功能的類
(2)具體組件:將要被附加功能的類,實現抽象構件角色接口
(3)抽象裝飾者:持有對具體構件角色的引用並定義與抽象構件角色一致的接口
(4)具體裝飾:實現抽象裝飾者角色,負責對具體構件添加額外功能。
六、代碼
Component
public interface Person { void eat(); }
ConcreteComponent
public class Man implements Person { public void eat() { System.out.println("男人在吃"); } }
Decorator
public abstract class Decorator implements Person { protected Person person; public void setPerson(Person person) { this.person = person; } public void eat() { person.eat(); } }
ConcreteDectrator
public class ManDecoratorA extends Decorator { public void eat() { super.eat(); reEat(); System.out.println("ManDecoratorA類"); } public void reEat() { System.out.println("再吃一頓飯"); } } public class ManDecoratorB extends Decorator { public void eat() { super.eat(); System.out.println("==============="); System.out.println("ManDecoratorB類"); } }
Test
public class Test { public static void main(String[] args) { Man man = new Man(); ManDecoratorA md1 = new ManDecoratorA(); ManDecoratorB md2 = new ManDecoratorB(); md1.setPerson(man); md2.setPerson(md1); md2.eat(); } }
七、裝飾者模式小結:
OO原則:動態地將責任附加到對象上。想要擴展功能, 裝飾者提供有別於繼承的另外一種選擇。
八、要點:
1、繼承屬於擴展形式之一,但不見得是達到彈性設計的最佳方案。
2、在咱們的設計中,應該容許行爲能夠被擴展,而不須修改現有的代碼。
3、組合和委託可用於在運行時動態地加上新的行爲。
4、除了繼承,裝飾者模式也可讓咱們擴展行爲。
5、裝飾者模式意味着一羣裝飾者類, 這些類用來包裝具體組件。
6、裝飾者類反映出被裝飾的組件類型(實際上,他們具備相同的類型,都通過接口或繼承實現)。
7、裝飾者能夠在被裝飾者的行爲前面與/或後面加上本身的行爲,甚至將被裝飾者的行爲整個取代掉,而達到特定的目的。
8、你能夠有無數個裝飾者包裝一個組件。
九、 裝飾者通常對組建的客戶是透明的,除非客戶程序依賴於組件的具體類型。