爲何會有裝飾模式?java
裝飾模式是爲了解決繼承強依賴性和出現大量子類不方便管理問題而出現的。ide
1. 概述函數
動態地給一個對象添加一些額外的職責,就增長功能來講,裝飾模式比生成子類更靈活。測試
原理:增長一個修飾類包裹原來的類,包裹的方式通常是經過在將原來的對象做爲修飾類的構造函數的參數。裝飾類實現新的功能,可是,在不須要用到新功能的地方,它能夠直接調用原來的類中的方法。修飾類必須和原來的類有相同的接口。this
2. 模式中的角色spa
2.1 抽象構建(Component):定義一個抽象接口,用以給這些對象動態地添加職責。設計
2.2 具體構建(ConcreteComponent):定義一個具體的對象,也能夠給這個對象添加一些職責。code
2.3 裝飾類(Decorator): 裝飾抽象類,繼承了Component,從外類來擴展Component類的功能。component
2.4 具體裝飾者(ConcretorDecorator):負責給構建對象添加職責。對象
類圖解析:
1)Component:抽象接口,用來統一規範準備被裝飾的對象。
2)Concrete Component:具體被裝飾類,定義一個將要被裝飾的類。
3) Decorator:抽象裝飾類,要求與被裝飾類擁有一致的接口(這個是必須的,不然沒有辦法將裝飾經過多態傳遞給 被裝飾對象)。
4)Concrete Decorator:具體裝飾類,負責給被裝飾對象添加功能。
3. 模式總結
3.1 優勢
3.1.1 每一個裝飾對象只關心本身的功能,不須要關心如何被添加到對象鏈當中。它是由Decorator的SetComponent方法來實現的,於是它們的職責是單一的。
3.1.2 類的核心職責與動態添加的職責是分離的。若是再向主類中添加新的功能,一是違反了開放封閉原則,二是增長了主類的複雜度。
3.1.3 比靜態繼承更靈活 與對象的靜態繼承相比,Decorator模式提供了更加靈活的向對象添加職責的方式,能夠使用添加和分離的方法,用裝飾在運行時刻增長和刪除職責.
3.2 缺點
3.2.1 產生許多小對象,採用Decorator模式進行系統設計每每會產生許多看上去相似的小對象,這些對象僅僅在他們相互鏈接的方式上有所不一樣。
3.3 適用場景
3.3.1 當須要爲已有功能動態地添加更多功能時。
3.3.2 類的核心功能無需改變,只是須要添加新的功能時。
四、代碼實現
若是隻有一個ConcreteComponent類而沒有抽象的Component類,那麼Decorator類能夠是ConcreteComponent的一個子類,同理,若是隻有一個ConcreteDecorator類,那麼就沒有必要創建一個單獨的Decorator類,而能夠把Decorator和ConcreteDecorator的責任合併成一個類。
so,在這列咱們不用Component類,直接讓服飾類Decorator繼承人類ConcreteComponent就可。
Person類
class Person{ private String name ; public Person(String name){ this.name = name; } public Person(){ } public void show(){ System.out.println("裝扮的" + name); } }服飾類
class Finery extends Person{ protected Person component; //打扮 public void Decorate(Person component){ this.component = component; } public void show(){ if(component != null){ component.show(); } } }
class TShirts extends Finery{ @Override public void show() { System.out.print("大TT恤 "); super.show(); } } class BigTrouser extends Finery{ @Override public void show() { System.out.print("垮褲 "); super.show(); } } class NewTrouser extends Finery{ @Override public void show() { System.out.print("新垮褲 "); super.show(); } }
public class 裝飾器模式 { public static void main(String[] args) { Person person = new Person("小菜"); TShirts t = new TShirts(); BigTrouser b = new BigTrouser(); NewTrouser n = new NewTrouser(); t.Decorate(person); b.Decorate(t); n.Decorate(b); n.show(); } }能夠看出,修飾模式總共有四部分組成,1)抽象被修飾類或接口;2)具體被修飾類;3)抽象修飾類;4)具體修飾類。