裝飾模式可以動態向乙個現有的物件新增新的功能,同時又不改變其結構。就增加功能來說,使用繼承的方式生成子類也可以達到目的,但隨著擴充套件功能的不斷增加,子類的數量會快速膨脹,而裝飾模式提供了一種更加靈活的方案。
gof對裝飾模式的描述為:
attach additional responsibilities to an object dynamically. decorators provide a flexible alternative to subclassing for extending functionality.
— design patterns : elements of reusable object-oriented software
uml類圖:
icomponent介面定義了現有的功能,concretecomponent是它的具體實現類。
為了給icomponent擴充套件功能,引入了idecorator介面,它繼承了icomponent介面,concretedecorator是擴充套件功能的具體實現。
為了更形象地理解這一模式,模擬實現乙個文字處理軟體功能,最初軟體只具備單純的文字輸入、顯示功能,後來擴充套件了更高階的功能,比如字型可以加粗、文字顏色可以調整、可以有不同的字型大小等等。
最初的功能
public inte***ce itext
}public class textobject : itext
}}
使用裝飾模式進行擴充套件
public inte***ce idecorator : itext
public abstract class decoratorbase : idecorator
public decoratorbase(itext target)
}//字型加粗
public class bolddecorator : decoratorbase
public override string content => changetoboldfont(target.content);
public string changetoboldfont(string content)";}
}//字型顏色
public class colordecorator : decoratorbase
public override string content => addcolortag(target.content);
public string addcolortag(string content)";}
}
測試**:
static void main(string args)
裝飾模式是設計模式中實現技巧性非常明顯的乙個模式,它的宣告要實現icomponent定義的方法,但同時又會保留乙個icomponent的成員,icomponent介面方法的實現其實是通過自己儲存的那個icomponent成員完成的,自己在這個基礎上增加一些額外的處理。
適用場景 缺點
裝飾模式雖然提供了比繼承更加靈活的擴充套件方案,但也存在一些缺點:
在實際場景中,除了動態增加功能,往往還需要動態撤銷某些功能,假設用裝飾模式來實現英雄聯盟中英雄購買裝備的過程,買一件裝備,就相當於動態為英雄增加功能,但如果後期公升級裝備需要賣掉一件現有的準備時,在實現上就涉及到這件裝備功能的解除安裝。
在比如前面**中的文書處理功能,字型加粗後可以撤銷,字型的顏色也支援更換,也需要功能的動態撤銷,接上面的例子,實現撤銷的功能需要結合後面會學到的狀態模式,新增istate介面,引入了狀態的概念
支援撤銷功能的**如下:
//引入了狀態的概念
public inte***ce istate
//字型是否加粗可以用bool來表示
public class boldstate : istate
return ((boldstate)newstate).isbold == isbold;
}}//字型顏色的狀態比較多
public class colorstate : istate
return ((colorstate)newstate).color == color;
}}//基本功能
public inte***ce itext
}public class textobject : itext }}
//裝飾介面,增加了狀態屬性和重新整理狀態的動作
public inte***ce idecorator : itext
void refresh(istate newstate) where t : idecorator;
}public abstract class decoratorbase : idecorator
public abstract string content
public istate state
//更新狀態
public virtual void refresh(istate newstate) where t : idecorator
if (state != null && !state.equals(newstate))
}if (target != null && typeof(idecorator).isassignablefrom(target.gettype()))
}}
public class bolddecorator : decoratorbase
public override string content";}
else}}
}public class colordecorator : decoratorbase
public override string content
>";
}else}}
}
測試**
static void main(string args)
設計模式9 裝飾器模式
裝飾器模式 decorator pattern 允許向乙個現有的物件新增新的功能,同時又不改變其結構。這種型別的設計模式屬於結構型模式,它是作為現有的類的乙個包裝。這種模式建立了乙個裝飾類,用來包裝原有的類,並在保持類方法簽名完整性的前提下,提供了額外的功能。裝飾器模式,從某種角度上說,可能更適合用...
設計模式 9 裝飾者模式
動態地將責任附加到物件上,若要擴充套件功能,裝飾者比繼承更有彈性 裝飾者將被裝飾聚合到自己內部,雙方都繼承共同的抽象方法,往往是被裝飾者只需要完成自己的本質工作,裝飾者在整合的被裝飾者功能基礎之上新增自己的邏輯。下面以飲品店咖啡和咖啡配料組合例子作為案例說明 public abstract clas...
設計模式 9 裝飾者模式
說明 給乙個類增加額外的功能,適合使用,stream就是使用裝飾者模式,有了memorystream,filestream,networkstream等。實現 public abstract class car public class baoma car 我要加功能,用裝飾者 public abs...