定義
動(dòng)態(tài)地給一個(gè)對象添加一些額外的職責(zé),就增加功能來說,裝飾模式相比生成子類更為靈活。其實(shí)通俗的說就說給一個(gè)類增加新的功能(解決java不能擴(kuò)展類方法的問題,kotlin改進(jìn)了java這個(gè)不能擴(kuò)展的問題)
使用場景
- 需要透明且動(dòng)態(tài)的擴(kuò)展類的功能時(shí)
其實(shí)就是擴(kuò)展父類
UML圖

裝飾模式.png

角色介紹
簡單的例子
人事要穿衣服的,將人定義為一個(gè)抽象類,將穿衣的行為定義為一個(gè)抽象方法
/** 人的抽象類,相當(dāng)于Component類
*
*/
public abstract class Person {
/**
*
* Person下有個(gè)穿著的抽象方法,
* */
public abstract void dressed();
}
Boy類繼承于Person類,該類僅對Person中的dresses方法做了具體的實(shí)現(xiàn),而Boy類就是我們所要裝飾的具體對象
/** Boy類,相當(dāng)于具體實(shí)現(xiàn)類ConcreteComponent類
*
*/
public class Boy extends Person {
@Override
public void dressed() {
System.out.println("原始穿著:內(nèi)衣內(nèi)褲");
}
}
裝飾者
**
* 抽象的裝飾類,類似Decorator類
*
*/
public abstract class PersonCloth extends Person {
protected Person mPerson;//保持一個(gè)Person類的引用
public PersonCloth(Person mPerson) {
this.mPerson = mPerson;
}
@Override
public void dressed() {
//調(diào)用Person類中的dressed方法
mPerson.dressed();
}
}
具體的裝飾類,其實(shí)就是為了Boy類提供擴(kuò)展
/** 昂貴的 本質(zhì)上僅僅是將原有方法和新邏輯進(jìn)行封裝整合了
* 具體的裝飾類,類似ConcreteDecoratorA
*
*/
public class ExpensiveCloth extends PersonCloth {
public ExpensiveCloth(Person mPerson) {
super(mPerson);
}
private void dressShirt() {
System.out.println("裝飾:穿上了短袖");
}
private void dressLeather() {
System.out.println("裝飾:穿上了皮衣");
}
private void dressJean() {
System.out.println("裝飾:穿上了牛仔褲");
}
@Override
public void dressed() {
super.dressed();//這里就是Boy類的原始方法,只穿內(nèi)褲內(nèi)衣
dressShirt();
dressLeather();
dressJean();
}
}
/** 便宜的
* 具體的裝飾類,類似ConcreteDecoratorA
*
*/
public class CheapCloth extends PersonCloth {
public CheapCloth(Person mPerson) {
super(mPerson);
}
private void dressShorts() {
System.out.println("裝飾:穿上了短褲");
}
@Override
public void dressed() {
super.dressed();
dressShorts();
}
}
** 測試類
*
*/
public class Test {
public static void main(String[] args){
//首先要有一個(gè)Person男孩
Person person = new Boy();
//然后為他穿上便宜的衣服
PersonCloth cheapCloth = new CheapCloth(person);
cheapCloth.dressed();
System.out.println();
System.out.println();
System.out.println();
//或者穿上貴的衣服
PersonCloth expensiveCloth = new ExpensiveCloth(person);
expensiveCloth.dressed();
}
}
結(jié)果:
原始穿著:內(nèi)衣內(nèi)褲
裝飾:穿上了短褲
原始穿著:內(nèi)衣內(nèi)褲
裝飾:穿上了短袖
裝飾:穿上了皮衣
裝飾:穿上了牛仔褲
例子UML類圖

優(yōu)點(diǎn)
- 擴(kuò)展類方法
缺點(diǎn)
- 和代理模式易混淆
裝飾模式:以對客戶端透明的方式擴(kuò)展對象的功能,是繼承關(guān)系的一個(gè)替代方案(為裝飾的對象增強(qiáng)功能)
代理模式:給對象提供一個(gè)代理對象,并用代理對象來控制對原有對象的引用(對代理的對象施加控制,但不對對象本身的功能進(jìn)行增強(qiáng))
源代碼:DesignPattern
參考:
《Android源碼設(shè)計(jì)模式解析與實(shí)戰(zhàn)讀書》
各大佬博客
end