設計模式 9 裝飾模式

2021-10-08 08:10:41 字數 3174 閱讀 4301

裝飾模式可以動態向乙個現有的物件新增新的功能,同時又不改變其結構。就增加功能來說,使用繼承的方式生成子類也可以達到目的,但隨著擴充套件功能的不斷增加,子類的數量會快速膨脹,而裝飾模式提供了一種更加靈活的方案。

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...