日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > asp.net >内容正文

asp.net

设计模式的征途—12.享元(Flyweight)模式

發(fā)布時(shí)間:2025/3/15 asp.net 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 设计模式的征途—12.享元(Flyweight)模式 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

現(xiàn)在在大力推行節(jié)約型社會(huì),“浪費(fèi)可恥,節(jié)儉光榮”。在軟件系統(tǒng)中,有時(shí)候也會(huì)存在資源浪費(fèi)的情況,例如,在計(jì)算機(jī)內(nèi)存中存儲(chǔ)了多個(gè)完全相同或者非常相似的對(duì)象,如果這些對(duì)象的數(shù)量太多將導(dǎo)致系統(tǒng)運(yùn)行代價(jià)過(guò)高。那么,是否存在一種技術(shù)可以用于節(jié)約內(nèi)存使用空間,實(shí)現(xiàn)對(duì)這些相同或者相似對(duì)象的共享訪問(wèn)呢?答案是肯定的,這種技術(shù)就是享元模式。

享元模式(Flyweight)學(xué)習(xí)難度:★★★★☆使用頻率:★☆☆☆☆

一、圍棋棋子的設(shè)計(jì)

M公司開(kāi)發(fā)部欲開(kāi)發(fā)一個(gè)圍棋軟件,其界面效果如下圖所示:

  M公司開(kāi)發(fā)人員通過(guò)對(duì)圍棋軟件進(jìn)行分析,發(fā)現(xiàn)在圍棋棋盤(pán)中包含大量的黑子和白子,它們的形狀、大小都一模一樣,只是出現(xiàn)的位置不同而已。如果將每一個(gè)棋子都作為一個(gè)獨(dú)立的對(duì)象存儲(chǔ)在內(nèi)存中,將可能導(dǎo)致該圍棋軟件在運(yùn)行時(shí)所需要的內(nèi)存空間較大。

  如何降低運(yùn)行代價(jià)、提高系統(tǒng)性能是M公司開(kāi)發(fā)人員需要解決的一個(gè)問(wèn)題。為此,M公司開(kāi)發(fā)人員決定使用享元模式來(lái)設(shè)計(jì)該軟件。

二、享元模式概述

2.1 享元模式簡(jiǎn)介

享元(Flyweight)模式:運(yùn)用共享技術(shù)有效地支持大量細(xì)粒度對(duì)象的復(fù)用。系統(tǒng)只使用少量的對(duì)象,而這些對(duì)象都很相似,狀態(tài)變化很小,可以實(shí)現(xiàn)對(duì)象的多次復(fù)用。由于享元模式要求能夠共享的對(duì)象必須是細(xì)粒度對(duì)象,因此它又稱(chēng)為輕量級(jí)模式,是一種結(jié)構(gòu)型模式。

2.2 享元模式結(jié)構(gòu)

  享元模式的結(jié)構(gòu)較為復(fù)雜,一般結(jié)合工廠模式一起使用,在其結(jié)構(gòu)圖中包含了一個(gè)享元工廠類(lèi),如下圖所示:

  由上圖可以看出,它包含了以下4個(gè)角色:

  (1)Flyweight(抽象享元類(lèi)):一個(gè)接口或抽象類(lèi),聲明了具體享元類(lèi)的公共方法。

  (2)ConcreteFlyweight(具體享元類(lèi)):實(shí)現(xiàn)了抽象享元類(lèi),其實(shí)例稱(chēng)為享元對(duì)象。

  (3)UnsharedConcreteFlyweight(非共享具體享元類(lèi)):并不是所有的抽象享元類(lèi)的子類(lèi)都需要被共享,不能被共享的子類(lèi)可設(shè)計(jì)為費(fèi)共享具體享元類(lèi)。

  (4)FlyweightFactory(享元工廠類(lèi)):用于創(chuàng)建并管理享元對(duì)象,一般設(shè)計(jì)為一個(gè)存儲(chǔ)“Key-Value”鍵值對(duì)的集合(可以結(jié)合工廠模式設(shè)計(jì))。其作用就在于:提供一個(gè)用于存儲(chǔ)享元對(duì)象的享元池,當(dāng)用戶(hù)需要對(duì)象時(shí),首先從享元池中獲取,如果享元池中不存在,那么則創(chuàng)建一個(gè)新的享元對(duì)象返回給用戶(hù),并在享元池中保存該新增對(duì)象。=> 想想.NET中的各種資源池的設(shè)計(jì)?

三、重構(gòu)后的圍棋棋子方案

3.1 重構(gòu)后的設(shè)計(jì)

  M公司開(kāi)發(fā)人員采用了享元模式進(jìn)行設(shè)計(jì),如下圖所示:

  其中,IgoChessman充當(dāng)抽象享元類(lèi),BlackIgoChessman和WhiteIgoChessman充當(dāng)具體享元類(lèi),IgoChessmanFactory充當(dāng)享元工廠類(lèi)。

3.2 具體代碼實(shí)現(xiàn)

  (1)抽象享元類(lèi):IgoChessman

public abstract class IgoChessman{public abstract string GetColor();public void Display(Coordinates coord){Console.WriteLine("棋子顏色:{0},棋子位置:{1}", GetColor(), coord.X + "," + coord.Y);}}/// <summary>/// 外部狀態(tài):棋子坐標(biāo)/// </summary>public class Coordinates{public int X { get; set; }public int Y { get; set; }public Coordinates(){}public Coordinates(int x, int y){this.X = x;this.Y = y;}}

  (2)具體享元類(lèi):BlackIgoChessman、WhiteIgoChessman

// 具體享元類(lèi)Apublic class BlackIgoChessman : IgoChessman{public override string GetColor(){return "黑色";}}// 具體享元類(lèi)Bpublic class WhiteIgoChessman : IgoChessman{public override string GetColor(){return "白色";}}

  (3)享元工廠類(lèi):IgoChessmanFactory

/// <summary>/// 享元工廠類(lèi)/// </summary>public class IgoChessmanFactory{private static readonly IgoChessmanFactory instance = new IgoChessmanFactory(); // 使用單例模式實(shí)現(xiàn)享元private static Hashtable ht; // 使用Hashtable來(lái)存儲(chǔ)享元對(duì)象,充當(dāng)享元池private IgoChessmanFactory(){ht = new Hashtable();IgoChessman blackChess = new BlackIgoChessman();ht.Add("b", blackChess);IgoChessman whiteChess = new WhiteIgoChessman();ht.Add("w", whiteChess);}public static IgoChessmanFactory GetInstance(){return instance;}public IgoChessman GetIgoChessman(string color){IgoChessman chess = ht[color] as IgoChessman;return chess;}}

  (4)客戶(hù)端調(diào)用

public class Program{public static void Main(string[] args){// 獲取享元工廠IgoChessmanFactory chessFactory = IgoChessmanFactory.GetInstance();// 通過(guò)享元工廠獲取3顆黑子IgoChessman blackChess1 = chessFactory.GetIgoChessman("b");IgoChessman blackChess2 = chessFactory.GetIgoChessman("b");IgoChessman blackChess3 = chessFactory.GetIgoChessman("b");Console.WriteLine("判斷兩顆黑子是否相同:{0}", object.ReferenceEquals(blackChess1, blackChess2));// 通過(guò)享元工廠獲取2顆白子IgoChessman whiteChess1 = chessFactory.GetIgoChessman("w");IgoChessman whiteChess2 = chessFactory.GetIgoChessman("w");Console.WriteLine("判斷兩顆白子是否相同:{0}", object.ReferenceEquals(whiteChess1, whiteChess2));// 顯示棋子blackChess1.Display(new Coordinates(1,2));blackChess2.Display(new Coordinates(3, 4));blackChess3.Display(new Coordinates(1, 3));whiteChess1.Display(new Coordinates(2, 5));whiteChess2.Display(new Coordinates(2, 4));Console.ReadKey();}}

  運(yùn)行結(jié)果如下圖所示:

  

  從運(yùn)行結(jié)果可以看出,在每次調(diào)用Display()方法時(shí),都設(shè)置了不同的外部狀態(tài)-坐標(biāo)值,因此相同的棋子雖然具有相同的顏色,但是它們的坐標(biāo)值不同,將顯示在棋盤(pán)的不同位置。

四、享元模式總結(jié)

4.1 主要優(yōu)點(diǎn)

  可以極大減少內(nèi)存中對(duì)象的數(shù)量,使得相同或相似對(duì)象在內(nèi)存中只有一份 => 節(jié)省系統(tǒng)資源,提高系統(tǒng)性能!棒棒噠!

4.2 主要缺點(diǎn)

  為了使對(duì)象可以共享,享元模式需要將享元對(duì)象的部分狀態(tài)外部化,而讀取外部狀態(tài)將使得運(yùn)行時(shí)間變長(zhǎng)!

4.3 應(yīng)用場(chǎng)景

  (1)一個(gè)系統(tǒng)有大量相同或相似的對(duì)象,造成了系統(tǒng)內(nèi)存的大量損耗 => 趕緊使用享元模式吧!

  (2)對(duì)象的大部分狀態(tài)都可以外部化,可以將這些外部狀態(tài)傳入對(duì)象中。

  (3)要維護(hù)享元模式,需要耗費(fèi)一定的系統(tǒng)資源,因?yàn)樵谛枰獣r(shí)會(huì)多次重復(fù)使用才值得使用享元模式了!

參考資料

  

  劉偉,《設(shè)計(jì)模式的藝術(shù)—軟件開(kāi)發(fā)人員內(nèi)功修煉之道》

?

作者:周旭龍

出處:http://edisonchou.cnblogs.com

本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文鏈接。

轉(zhuǎn)載于:https://www.cnblogs.com/edisonchou/p/7148258.html

總結(jié)

以上是生活随笔為你收集整理的设计模式的征途—12.享元(Flyweight)模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。