设计模式 之 享元
享元模式(Flyweight)
? ? ? ? ? 運用共享技術有效地支持大量細粒度的對象。
? ? ? ? 還記得那年夏天一起在作文本上玩過的五子棋嗎?五子棋是一種兩人對弈的純策略型棋類游戲,它起源于中國古代的傳統黑白棋種之中的一個,不僅能增強思維能力,提高智力,并且富含哲理,有助于修身養性。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? 假設我們要做一個五子棋游戲的程序,該怎么做呢?看看五子棋游戲中的棋子,就是“黑子”和“白子”兩種類型,假設每次都創建一個新的對象實例,是不是太消耗系統內存了呢?以下就為大家解決這一問題
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections;namespace 享元模式 {//抽象棋子類public abstract class AbstractChessman{//棋子坐標protected int x;protected int y;//棋子類別(黑|白)protected string chess;public AbstractChessman (string chess){this.chess = chess;}//點坐標設置public abstract void point(int x,int y);//顯示棋子信息public void show(){Console.WriteLine(this.chess+ "("+this.x+","+this.y +")");}}//黑色棋子實現public class BlackChessman :AbstractChessman{public BlackChessman(): base("●"){Console.WriteLine("--BlackChessman Construction Exec!!!");}public override void point(int x,int y){this.x = x;this.y = y;this.show();}}//白色棋子實現public class WhiteChessman :AbstractChessman{public WhiteChessman(): base("○"){Console.WriteLine("--WhiteChessman Construction Exec!!!");}public override void point(int x, int y){this.x = x;this.y = y;this.show();}}//創建棋子工廠public class FiveChessmanFactory{//單例模式工廠private static FiveChessmanFactory fiveChessmanFactory = new FiveChessmanFactory();//緩存存放共享對象private Hashtable cache = new Hashtable();//私有化構造方法private FiveChessmanFactory(){ }//獲得單例工廠public static FiveChessmanFactory getInstance(){return fiveChessmanFactory;}public AbstractChessman getChessmanObject(string c){//從緩存中獲得棋子對象實例AbstractChessman abstractChessman = (AbstractChessman)this.cache[c];if (abstractChessman == null){//緩存中沒有棋子對象實例信息,則創建棋子對象實例,并放入緩存switch (c){case "B":abstractChessman = new BlackChessman();break;case "W":abstractChessman = new WhiteChessman();break;default:break;}//為防止非法字符的進入,返回nullif (abstractChessman !=null){cache.Add(c, abstractChessman);}}return abstractChessman;}}class Program{static void Main(string[] args){//創建五子棋工廠FiveChessmanFactory fiveChessmanFactory = FiveChessmanFactory.getInstance();//隨機數,用來生成棋子對象Random random = new Random();int radom = 0;AbstractChessman abstractChessman = null;for (int i = 0; i < 10; i++){radom = random.Next(2);switch (radom){case 0:abstractChessman = fiveChessmanFactory.getChessmanObject("B");break;case 1:abstractChessman = fiveChessmanFactory.getChessmanObject("W");break;}if (abstractChessman !=null){//設置棋子位置信息abstractChessman.point(i, random.Next(15));}}}} }
享元模式類圖:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
在類圖中包括例如以下幾個角色:
? ? ? ??Flyweight(抽象享元角色):全部詳細享元的超類,為詳細享元類規定出須要實現的公共接口。
? ? ? ??ConcreteFlyweight(詳細享元角色):實現抽象享元角色所規定的接口。假設有內含狀態,則必須負責為內含狀態提供存儲空間。
? ? ? ??FlyweightFactory(享元工廠角色):負責創建和管理享元角色。必須保證享元對象能夠被系統適當地共享。
主要長處:
? ? ? ? 1.能夠極大降低內存中對象的數量,使得同樣或相似對象在內存中僅僅保存一份,從而能夠節約系統資源,提高系統性能。
? ? ? ? 2.享元模式的外部狀態相對獨立,并且不會影響其內部狀態,從而使得享元對象能夠在不同的環境中被共享。
主要缺點:
? ? ? ? 1.享元模式使得系統變得復雜,須要分離出內部狀態和外部狀態,這使得程序的邏輯復雜化。
? ? ? ? 2.為了使對象能夠共享,享元模式須要將享元對象的部分狀態外部化,而讀取外部狀態將使得執行時間變長。
適用場景:
? ? ? ? 1.當系統中某個對象類型的實例較多的時候。
? ? ? ? 2. 對象的大部分狀態都能夠外部化,能夠將這些外部狀態傳入對象中。
? ? ? ??
相關的設計模式
? ? ? ? 1.組合:能夠使用享元共享組合中的葉子節點,從而提高系統的處理效率。
? ? ? ? 2.單例:在享元中,一般都是想享元工廠設置為單例,以減少系統使用空間。單例本身就是一種享元!單例僅僅有一個對象實例,被其它對象所共享。
? ? ? ? ? 運用共享技術有效地支持大量細粒度的對象。
? ? ? ? 還記得那年夏天一起在作文本上玩過的五子棋嗎?五子棋是一種兩人對弈的純策略型棋類游戲,它起源于中國古代的傳統黑白棋種之中的一個,不僅能增強思維能力,提高智力,并且富含哲理,有助于修身養性。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? 假設我們要做一個五子棋游戲的程序,該怎么做呢?看看五子棋游戲中的棋子,就是“黑子”和“白子”兩種類型,假設每次都創建一個新的對象實例,是不是太消耗系統內存了呢?以下就為大家解決這一問題
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections;namespace 享元模式 {//抽象棋子類public abstract class AbstractChessman{//棋子坐標protected int x;protected int y;//棋子類別(黑|白)protected string chess;public AbstractChessman (string chess){this.chess = chess;}//點坐標設置public abstract void point(int x,int y);//顯示棋子信息public void show(){Console.WriteLine(this.chess+ "("+this.x+","+this.y +")");}}//黑色棋子實現public class BlackChessman :AbstractChessman{public BlackChessman(): base("●"){Console.WriteLine("--BlackChessman Construction Exec!!!");}public override void point(int x,int y){this.x = x;this.y = y;this.show();}}//白色棋子實現public class WhiteChessman :AbstractChessman{public WhiteChessman(): base("○"){Console.WriteLine("--WhiteChessman Construction Exec!!!");}public override void point(int x, int y){this.x = x;this.y = y;this.show();}}//創建棋子工廠public class FiveChessmanFactory{//單例模式工廠private static FiveChessmanFactory fiveChessmanFactory = new FiveChessmanFactory();//緩存存放共享對象private Hashtable cache = new Hashtable();//私有化構造方法private FiveChessmanFactory(){ }//獲得單例工廠public static FiveChessmanFactory getInstance(){return fiveChessmanFactory;}public AbstractChessman getChessmanObject(string c){//從緩存中獲得棋子對象實例AbstractChessman abstractChessman = (AbstractChessman)this.cache[c];if (abstractChessman == null){//緩存中沒有棋子對象實例信息,則創建棋子對象實例,并放入緩存switch (c){case "B":abstractChessman = new BlackChessman();break;case "W":abstractChessman = new WhiteChessman();break;default:break;}//為防止非法字符的進入,返回nullif (abstractChessman !=null){cache.Add(c, abstractChessman);}}return abstractChessman;}}class Program{static void Main(string[] args){//創建五子棋工廠FiveChessmanFactory fiveChessmanFactory = FiveChessmanFactory.getInstance();//隨機數,用來生成棋子對象Random random = new Random();int radom = 0;AbstractChessman abstractChessman = null;for (int i = 0; i < 10; i++){radom = random.Next(2);switch (radom){case 0:abstractChessman = fiveChessmanFactory.getChessmanObject("B");break;case 1:abstractChessman = fiveChessmanFactory.getChessmanObject("W");break;}if (abstractChessman !=null){//設置棋子位置信息abstractChessman.point(i, random.Next(15));}}}} }
享元模式類圖:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
在類圖中包括例如以下幾個角色:
? ? ? ??Flyweight(抽象享元角色):全部詳細享元的超類,為詳細享元類規定出須要實現的公共接口。
? ? ? ??ConcreteFlyweight(詳細享元角色):實現抽象享元角色所規定的接口。假設有內含狀態,則必須負責為內含狀態提供存儲空間。
? ? ? ??FlyweightFactory(享元工廠角色):負責創建和管理享元角色。必須保證享元對象能夠被系統適當地共享。
主要長處:
? ? ? ? 1.能夠極大降低內存中對象的數量,使得同樣或相似對象在內存中僅僅保存一份,從而能夠節約系統資源,提高系統性能。
? ? ? ? 2.享元模式的外部狀態相對獨立,并且不會影響其內部狀態,從而使得享元對象能夠在不同的環境中被共享。
主要缺點:
? ? ? ? 1.享元模式使得系統變得復雜,須要分離出內部狀態和外部狀態,這使得程序的邏輯復雜化。
? ? ? ? 2.為了使對象能夠共享,享元模式須要將享元對象的部分狀態外部化,而讀取外部狀態將使得執行時間變長。
適用場景:
? ? ? ? 1.當系統中某個對象類型的實例較多的時候。
? ? ? ? 2. 對象的大部分狀態都能夠外部化,能夠將這些外部狀態傳入對象中。
? ? ? ??
相關的設計模式
? ? ? ? 1.組合:能夠使用享元共享組合中的葉子節點,從而提高系統的處理效率。
? ? ? ? 2.單例:在享元中,一般都是想享元工廠設置為單例,以減少系統使用空間。單例本身就是一種享元!單例僅僅有一個對象實例,被其它對象所共享。
轉載于:https://www.cnblogs.com/bhlsheji/p/4209208.html
總結
- 上一篇: 【百度地图API】发布静态图API啦!只
- 下一篇: 【转】在.Net中关于AOP的实现