網關上的請求頭和響應頭 當您通過MSE網關將請求轉發到後端服務時,在網關中添加的請求頭(例如 "hello")會在到達後端服務時一併發送給後端服務。您可以在後端服務中通過請求頭獲取該值。 當您在MSE網關中添加響應頭(例如 "good"),該響應頭會在後端服務完成響應之後,由MSE網關添加到響應中。 ...
基本介紹:
享元模式的定義:運用共用技術有效地支持大量細粒度的對象重覆使用。適用於大量小粒度的對象造成的運行效率和記憶體使用效率低下的情況。
“享元”顧名思義,“享”共用的意思,“元”單元,最小對象,零部件的意思。
即從字面意思不難看出,該模式旨在共用一些零部件供其使用。
想要實現對這些零部件的重覆使用,那必然需要一個類來統籌安排,負責它們的創建、使用和維護。
如果想要實現一個零部件的使用,可以使用單例模式,所以享元模式其實也可以看做是單例模式的複數模式。
它們都是在一個固定類中對對象進行創建和維護。
舉例說明:
比如五子棋游戲,構成游戲的組件,無非就是無數個黑棋和白棋。
黑棋和白棋就可以看做是兩個最小的單元,在對戰過程中就是在重覆的創建這些單元。
如果是一般模式一盤棋局必然要創建N多個黑棋和白棋的對象,如果是一盤游戲還可以湊合使用。
大家想象一下,如果是個游戲平臺,可以同時開展1000盤這樣的棋局,那必然需要創建N*1000個黑白棋子對象。
其實這些對象都是重覆的,只有很少一部分屬性(狀態)不同而已,相同的是棋子本身,不同的是棋子的顏色,比如黑棋和白棋之分。
另外該棋子在哪個棋盤、在哪個棋盤坐標就屬於不可被共用的部分了,這部分內容就是非共用的。
既然弄清楚了相同的部分和不同部分,我們就可以把相同的部分進行共用,對象個數從原來的N*1000個對象降到了2個對象。
基本結構:
通過例子也不難看出,享元模式創建的對象存在兩個狀態:
內部狀態:可以被共用的狀態。存儲在享元信息內部,並且不會隨環境的改變而改變。在這裡指的是棋子本身,它們不會隨著棋局和選手的變化而變化。
外部狀態:不可被共用的狀態。隨環境的改變而改變。在這裡指的是黑白棋子顏色之分。
這裡容易讓人產生誤區,容易把棋子所處坐標和棋盤等歸在外部狀態,這就大錯特錯了。
能共用的都是最基本的單元,而棋子的坐標和棋盤是不斷變化的,隨著棋局的不同而不同,這部分是不可以被共用的,也不能被共用。
享元模式的主要有以下角色:
抽象享元角色(Flyweight):通常是一個介面或抽象類,聲明瞭具體享元類公共的方法,這些方法可以為外界提供內部狀態和設置外部狀態。
具體享元角色(Concrete Flyweight):實現了抽象享元類,在該類中為內部狀態提供了存儲空間。通常我們可以結合單例模式來設計具體享元類,為每一個具體享元類提供唯一的享元對象。
非享元角色 (Unsharable Flyweight):並不是所有的抽象享元類的子類都需要被共用,不能被共用的子類可設計為非共用具體享元類;當需要一個非共用具體享元類的對象時可以直接通過實例化創建。本實例中,棋盤類就是非享元部分。
享元工廠角色(Flyweight Factory):負責創建和管理享元角色。當客戶對象請求一個享元對象時,享元工廠檢査系統中是否存在符合要求的享元對象,如果存在則提供給客戶;如果不存在的話,則創建一個新的享元對象。
優缺點:
優點:降低了系統中對象的數量,從而降低了系統中細粒度對象給記憶體帶來的壓力。享元模式中的外部狀態相對獨立,且不影響內部狀態。
缺點:為了使對象可以共用,需要將享元對象的部分狀態外部化,分離內部狀態和外部狀態,這使得程式的邏輯更複雜,使系統複雜化。
具體實例:
-
抽象享元角色
1 /// <summary> 2 /// 享元抽象類 3 /// </summary> 4 public abstract class ChessPieces 5 { 6 public string Colour; 7 public ChessPieces(string strColour) 8 { 9 Colour = strColour; 10 } 11 12 13 /// <summary> 14 /// 落子規則 15 /// </summary> 16 /// <param name="chessBoard">棋盤信息</param> 17 public void MoveInChess(ChessBoard chessBoard) 18 { 19 //這裡可以將棋盤信息通過參數方式註入 20 } 21 22 //還可以設置一些 棋子的規則等等 23 }
享元抽象類主要是規範具體享元類供其繼承,並提供其共有的屬性和方法。
本實例只是最簡單的使用構造函數參數註入方式,將棋子外部狀態(顏色)更新。
而內部狀態,比如棋子的具體下棋規則等等,可以在此類中聲明。
比如此實例MoveInChess方法就是通過參數註入的形式將棋盤信息註入到內容,從而落實落子的具體規則。
規則是通用的,可以共用的,所以可以是內部狀態的一部分。
- 具體享元角色
1 /// <summary> 2 /// 白棋 3 /// </summary> 4 public class BlackPieces : ChessPieces 5 { 6 public BlackPieces(string strColour) : base(strColour) 7 { 8 9 } 10 } 11 12 /// <summary> 13 /// 黑棋 14 /// </summary> 15 public class WhitePieces : ChessPieces 16 { 17 public WhitePieces(string strColour) : base(strColour) 18 { 19 20 } 21 }
繼承自抽象享元類,具體實現其方法。
此實例只是通過構造函數簡單的將棋子分成黑白棋子,實際中會有各種屬性或方法需要在此類中實現。
- 享元工廠角色
/// <summary> /// 棋子工廠 /// </summary> public class WuziqiFactory { // 單例模式工廠 private static WuziqiFactory wuziqiFactory; // 緩存存放共用對象 private static Dictionary<string, ChessPieces> keyValuePairs = new Dictionary<string, ChessPieces>(); // 私有化構造方法 private WuziqiFactory() { if (keyValuePairs.Count == 0) { keyValuePairs.Add("Black", new BlackPieces("Black")); keyValuePairs.Add("White", new WhitePieces("White")); } } // 獲得單例工廠 public static WuziqiFactory GetInstance { get { if (wuziqiFactory == null) { wuziqiFactory = new WuziqiFactory(); } return wuziqiFactory; } } // 獲取棋子 public ChessPieces GetChessPieces(String type) { if (keyValuePairs.ContainsKey(type)) { return keyValuePairs[type]; } return null; } }
此實例使用單例模式創建工廠對象,保證整個項目生命周期內只存在一個棋子工廠對象,並使用GetInstance進行返回具體對象。這裡可以加上鎖防止併發等問題。
另外工廠的構造函數對可共用對象進行了緩存,使用GetChessPieces獲取棋子對象時,可保證其不重覆創建。保證整個項目生命周期內只存在黑白兩個棋子對象。
- 非享元角色
1 /// <summary> 2 /// 棋盤 3 /// </summary> 4 public class ChessBoard 5 { 6 //棋盤編號 7 public int ChessBoardId { get; set; } 8 9 10 //黑方棋手 11 //白方棋手 12 //棋盤棋子佈局等等屬性 13 14 /// <summary> 15 /// 初始化棋盤 16 /// </summary> 17 public ChessBoard() 18 { 19 //可以通過構造函數 初始化棋盤基礎屬性 20 } 21 }
非享元部分,也就是不能共用的部分。
棋盤的編號、棋盤對局雙方信息和棋盤落子情況等都是每個棋盤獨有的,不可共用。
至於棋盤的落子和整體維護可以通過參數註入等形式交給棋子共用對象進行研判和操作,或者直接在棋盤類中進行聲明都可以,這就看具體制定的規則了。
-
客戶端
1 /// <summary> 2 /// 客戶端 3 /// </summary> 4 class Client 5 { 6 static void Main(string[] args) 7 { 8 //創建棋盤 通過構造函數或者函數參數等形式初始化棋手、棋盤信息 9 ChessBoard chessBoard = new ChessBoard(); 10 //獲取黑方棋子1 11 ChessPieces blackPieces1 = WuziqiFactory.GetInstance.GetChessPieces("Black"); 12 Console.WriteLine("棋子:" + blackPieces1.Colour); 13 //獲取白方棋子1 14 ChessPieces whitePieces1 = WuziqiFactory.GetInstance.GetChessPieces("White"); 15 Console.WriteLine("棋子:" + whitePieces1.Colour); 16 17 //判斷兩個棋子是否是同一個對象 18 Console.WriteLine("判斷兩個不同顏色的棋子是否是同一個對象" + blackPieces1.Equals(whitePieces1) + "\r\n"); 19 20 //獲取黑方棋子2 21 ChessPieces blackPieces2 = WuziqiFactory.GetInstance.GetChessPieces("Black"); 22 Console.WriteLine("棋子:" + blackPieces2.Colour); 23 //獲取白方棋子2 24 ChessPieces whitePieces2 = WuziqiFactory.GetInstance.GetChessPieces("White"); 25 Console.WriteLine("棋子:" + whitePieces2.Colour); 26 27 //判斷同一個顏色的兩個棋子是否是同一個對象 28 Console.WriteLine("判斷兩個不同顏色的棋子是否是同一個對象" + blackPieces1.Equals(blackPieces2) + "\r\n"); 29 30 Console.ReadKey(); 31 } 32 }
總結:
實現享元工廠類時使用單例模式和簡單工廠模式,確保對象的唯一性,並提供方法向客戶端返回享元對象。
作者:少年真愛 出處:https://www.cnblogs.com/mingnianjiehunba/p/17749285.html 博主的文章沒有高度、深度和廣度,只是湊字數。由於博主的水平不高,不足和錯誤之處在所難免,希望大家能夠批評指出。 博主是利用讀書、參考、引用、抄襲、複製和粘貼等多種方式打造成自己的文章,請原諒博主成為一個無恥的文檔搬運工!