设计模式 之 享元

来源:互联网 发布:格式工厂 for mac 编辑:程序博客网 时间:2024/05/20 17:27
享元模式(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;                }                //为防止非法字符的进入,返回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.单例:在享元中,一般都是想享元工厂设置为单例,以降低系统使用空间。单例本身就是一种享元!单例只有一个对象实例,被其他对象所共享。









21 0
原创粉丝点击