zoukankan      html  css  js  c++  java
  • 设计模式 之 享元

    享元模式(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.单例:在享元中,一般都是想享元工厂设置为单例,以减少系统使用空间。单例本身就是一种享元!单例仅仅有一个对象实例,被其它对象所共享。









  • 相关阅读:
    有趣的linux指令
    Linux——文件打包与压缩
    linux点滴记录
    不归零法编码、曼彻斯特编码和差分曼彻斯特编码
    MySQL点滴记录
    hdu 1200 To and Fro(简单模拟或DP)
    hdu 1081 To The Max(dp+化二维为一维)
    抓起根本(二)(hdu 4554 叛逆的小明 hdu 1002 A + B Problem II,数字的转化(反转),大数的加法......)
    抓其根本(一)(hdu2710 Max Factor 素数 最大公约数 最小公倍数.....)
    hdu 1159 Common Subsequence(最长公共子序列 DP)
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4209208.html
Copyright © 2011-2022 走看看