首页 > 代码库 > 设计模式 之 享元
设计模式 之 享元
享元模式(Flyweight)
运用共享技术有效地支持大量细粒度的对象。
还记得那年夏天一起在作文本上玩过的五子棋吗?五子棋是一种两人对弈的纯策略型棋类游戏,它起源于中国古代的传统黑白棋种之一,不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。
如果我们要做一个五子棋游戏的程序,该怎么做呢?看看五子棋游戏中的棋子,就是“黑子”和“白子”两种类型,如果每次都创建一个新的对象实例,是不是太消耗系统内存了呢?下面就为大家解决这一问题
享元模式类图:
在类图中包含如下几个角色:
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; } //为防止非法字符的进入,返回null if (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.单例:在享元中,一般都是想享元工厂设置为单例,以降低系统使用空间。单例本身就是一种享元!单例只有一个对象实例,被其他对象所共享。
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。