一、定義 動態地給一個對象增加一些額外的職責。就擴展功能而言,裝飾模式提供了一種比使用子類更加靈活的替代方案。裝飾模式是一種結構型模式。 二、描述 包含以下三個角色:1、Component(抽象構件):它是具體構件和抽象裝飾類的父類,聲明瞭在具體構件中實現的業務方法,它的引入可以是客戶端以一致的方式 ...
一、定義
動態地給一個對象增加一些額外的職責。就擴展功能而言,裝飾模式提供了一種比使用子類更加靈活的替代方案。裝飾模式是一種結構型模式。
二、描述
包含以下三個角色:1、Component(抽象構件):它是具體構件和抽象裝飾類的父類,聲明瞭在具體構件中實現的業務方法,它的引入可以是客戶端以一致的方式處理未被裝飾的對象以及裝飾之後的對象,實現客戶端的透明操作。
2、ConcreteComponent(具體構件):它是抽象構件的子類,用於定義具體的構件對象,實現了在抽象構件中聲明的方法,裝飾類可以給它增加額外的職責(方法)。
3、Decorator(抽象裝飾類):它也是抽象構件類的子類,用於給具體構件增加職責,但是具體職責在其子類中實現。它維護一個指向抽象構件對象的引用,通過該引用可以調用裝飾之前構件對象的方法,並通過其子類擴展該方法,以達到裝飾的目的。
4、ConcreteDecorator(具體裝飾類):它是抽象裝飾類的子類,負責向構件添加新的職責。每一個具體裝飾類都定義了一些新的行為,它可以調用在抽象裝飾類中定義的方法,並可以增加新的方法,以擴展對象的行為。
三、例子
X公司開發部基於OO技術開發了一套圖形界面構件庫Visual Component,該構件庫提供了大量的基本構件,如窗體、文本框、列表框等等,由於在使用該構件庫時,用戶經常要求定製一些特殊的顯示效果,例如帶滾動條的窗體,帶黑色邊框的文本框,即帶滾動條又帶黑色邊框的列表框等,因此經常需要對該構件庫進行擴展以增強其功能。Component:抽象界面構件類,充當抽象構件
public abstract class Component
{
public abstract void Display();
}
Window、TextBox、ListBox:窗體、文本框、列表框類,充當具體構件類
public class Window : Component
{
public override void Display()
{
Console.WriteLine("顯示窗體!");
}
}
public class TextBox : Component
{
public override void Display()
{
Console.WriteLine("顯示文本框!");
}
}
public class ListBox : Component
{
public override void Display()
{
Console.WriteLine("顯示列表框!");
}
}
ComponentDecorator:構件裝飾類,充當抽象裝飾類
public class ComponentDecorator : Component
{
private Component component;
public ComponentDecorator (Component component)
{
this.component = component;
}
public override void Display()
{
component.Display();
}
}
ScrollBarDecorator、BlackBorderDecorator:滾動條裝飾類、黑色邊框裝飾類,充當具體裝飾類
public class ScrollBarDecorator : ComponentDecorator
{
public ScrollBarDecorator(Component component) : base(component)
{
}
public override void Display()
{
this.SetScrollBar();
base.Display();
}
public void SetScrollBar()
{
Console.WriteLine("為構件增加滾動條!");
}
}
public class BlackBorderDecorator : ComponentDecorator
{
public BlackBorderDecorator(Component component) : base(component)
{
}
public override void Display()
{
this.SetScrollBar();
base.Display();
}
public void SetScrollBar()
{
Console.WriteLine("為構件增加黑色邊框!");
}
}
Program:客戶端測試類
Component component = new Window();
Component componentSB = new ScrollBarDecorator(component);
componentSB.Display();
Component componentBB = new BlackBorderDecorator(componentSB);
componentBB.Display();
Console.ReadLine();
四、總結
1、優點
(1)對於擴展一個對象的功能,裝飾模式比繼承更加靈活,不會導致類的個數急劇增加。
(2)裝飾模式可以通過一種動態的方式來擴展一個對象的功能,通過配置實現不同的行為。
(3)可以對一個對象進行多次裝飾,從而創造出很多不同行為的組合,得到功能更為強大的對象。
(4)具體構件類與具體裝飾類可以獨立變化,可以根據需要增加新的具體構建和具體裝飾,原有代碼無需修改,符合開放封閉原則。
2、缺點
(1)使用裝飾模式進行系統設計時將產生很多小對象,這些對象的區別在於它們之間相互連接的方式有所不同,而不是它們的類或者屬性值有所不同,大量小對象的產生勢必會占用更多的系統資源,在一定程度上影響程式的性能。
(2)雖然裝飾模式拱了一種比繼承更加靈活機動的方案,但同時也意味著比繼承更加易於出錯,排錯也很困難。特別是經過多次裝飾的對象,調試時尋找錯誤可能需要逐級排查,較為繁瑣。