目錄 1. 說明 2. 應(yīng)用場景 3. 結(jié)構(gòu)圖 4. 構(gòu)成 5. 適用性 6. 優(yōu)點 7. 缺點 8. java示例
1. 說明
1.動態(tài)地給一個對象添加一些額外的職責(zé) 。 2.Decorator Pattern。 3.就增加功能而言,裝飾器模式比生成子類更加靈活。 4.一種在不改變現(xiàn)有對象結(jié)構(gòu)的情況下,動態(tài)地給對象增加一些職責(zé)(即增加額外功能)的設(shè)計模式。 5.屬于對象結(jié)構(gòu)型模式。
2. 應(yīng)用場景
1.擴展功能 :當(dāng)需要給某個對象添加額外的功能,但又不想修改其源代碼或結(jié)構(gòu)時,可以使用裝飾器模式。例如,在軟件開發(fā)中,可以使用裝飾器模式來擴展類的功能,而無需創(chuàng)建新的子類。 2.動態(tài)代理 :裝飾器模式允許在運行時動態(tài)地給對象添加或撤銷功能。這對于需要動態(tài)修改對象行為的場景非常有用。 3.緩存功能 :通過裝飾器模式,可以為對象添加緩存功能,以提高系統(tǒng)的性能。例如,可以在數(shù)據(jù)訪問層使用裝飾器模式來緩存數(shù)據(jù),減少對數(shù)據(jù)庫的頻繁訪問。 4.日志記錄 :在系統(tǒng)中,經(jīng)常需要記錄對象的操作歷史或狀態(tài)變化。通過裝飾器模式,可以輕松地給對象添加日志記錄功能,方便后續(xù)的調(diào)試和錯誤追蹤。 5.用戶界面定制 :在圖形用戶界面(GUI)設(shè)計中,可以使用裝飾器模式來定制和擴展控件的功能。例如,可以為按鈕添加動畫效果、改變樣式或添加額外的交互功能。 6.文件處理 :在處理文件時,可以使用裝飾器模式來添加各種文件處理功能,如壓縮、加密、解密等。這樣,用戶可以根據(jù)需要選擇不同的裝飾器來處理文件。 7.網(wǎng)絡(luò)請求 :在發(fā)送網(wǎng)絡(luò)請求時,可以使用裝飾器模式來添加各種請求處理功能,如超時重試、身份驗證、請求簽名等。這些功能可以在不修改原始請求代碼的情況下動態(tài)地添加到請求中。 8.數(shù)據(jù)處理 :在處理數(shù)據(jù)時,可以使用裝飾器模式來添加各種數(shù)據(jù)處理功能,如排序、過濾、轉(zhuǎn)換等。這些功能可以根據(jù)需要動態(tài)地添加到數(shù)據(jù)處理流程中。
3. 結(jié)構(gòu)圖
4. 構(gòu)成
1.Commponent(抽象組件):定義一個對象接口,可以給這些對象動態(tài)地添加職責(zé)。定義一個接口或抽象類,規(guī)定被裝飾對象的行為。 2.ConcreteComponent(具體組件):定義一個對象,可以給這個對象添加職責(zé)。實現(xiàn)抽象組件接口或繼承抽象組件類,是裝飾器模式中的原始對象。 3.Decorator(抽象裝飾器):維持一個指向Component對象的指針,并定義一個與Component接口一致的接口。繼承或?qū)崿F(xiàn)抽象組件接口,并持有一個指向抽象組件的引用。抽象裝飾器通常還包含一些用于增加額外功能的方法。 4.ConcreteDecorator(具體裝飾器):向組件添加職責(zé)。繼承抽象裝飾器類,并實現(xiàn)具體的額外功能。具體裝飾器可以根據(jù)需要添加多個,以實現(xiàn)不同的效果。
5. 適用性
1.在不影響其他對象的情況下,以動態(tài)、透明的方式給單個對象添加職責(zé)。 2.處理那些可以撤銷的職責(zé) 3.當(dāng)不能采用生成子類的方式進行擴充時。一種情況是,可能有大量獨立的擴展,為支持每一種組合將產(chǎn)生大量的子類,使得子類數(shù)目呈爆炸性增長。另一種情況可能是,由于類定義被隱藏,或類定義不能用于生成子類。
6. 優(yōu)點
1.靈活性 :裝飾器是繼承的有力補充,比繼承更加靈活。它可以在不改變原有對象的情況下,動態(tài)地給一個對象擴展功能,實現(xiàn)即插即用。 2.可擴展性 :通過使用不同的裝飾類以及這些裝飾類的排列組合,可以實現(xiàn)不同的效果,滿足不同的需求。 3.遵循開閉原則 :裝飾器模式在擴展功能時,不需要修改原有類的代碼,符合開閉原則(對擴展開放,對修改關(guān)閉)。
7. 缺點
1.增加復(fù)雜性 :裝飾器模式會增加許多子類,過度使用會增加程序的復(fù)雜性。 2.難以理解 :如果裝飾器類過多,可能會使代碼變得難以理解和維護。
8. java示例
package com.learning.decorator.person;/*** 抽象組件* 定義一個人的接口* 獲取人的描述*/
public interface Person {String getDescription();
}
package com.learning.decorator.person;/*** 基礎(chǔ)的人* 具體組件*/
public class BasePerson implements Person {/*** 人的姓名*/private String name; public BasePerson(String name) { this.name = name; } @Override public String getDescription() { return name; }
}
package com.learning.decorator.person;/*** 抽象裝飾器* 衣服裝飾器*/
public abstract class ClothingDecorator implements Person {//被裝飾的對象protected Person person; public ClothingDecorator(Person person) { this.person = person; } @Override public String getDescription() { return decorate(person.getDescription()); } protected abstract String decorate(String description);
}
package com.learning.decorator.person;/*** 具體裝飾器* 帽子裝飾器*/
public class HatDecorator extends ClothingDecorator {public HatDecorator(Person person) { super(person); }/*** 帽子裝飾,戴了一個帽子* @param description* @return*/@Override protected String decorate(String description) { return description + "戴了一個帽子";}
}
package com.learning.decorator.person;/*** 具體裝飾器* 毛巾裝飾器*/
public class ScarfDecorator extends ClothingDecorator {public ScarfDecorator(Person person) { super(person); }/*** 覆蓋父類的方法, 戴了一條圍巾* @param description* @return*/@Override protected String decorate(String description) { return description + "戴了一條圍巾";}
}
package com.learning.decorator.person;public class Client {public static void main(String[] args) { Person person = new BasePerson("張三");System.out.println(person.getDescription());Person personWithHat = new HatDecorator(person);System.out.println(personWithHat.getDescription());Person personWithHatAndScarf = new ScarfDecorator(personWithHat);System.out.println(personWithHatAndScarf.getDescription());}
}
7.示例截圖