C#面向对象设计之——享元模式(十二)

一、前言

运用共享模式能够有效地支持大量细粒度的对象。

二、结构图

三、实例代码

namespace 享元模式
{
    class Program
    {
        static void Main(string[] args)
        {
            int extrinsicstate = 22;

            FlyweightFactory f = new FlyweightFactory();

            Flyweight fx = f.GetFlyweight("X");
            fx.Operation(--extrinsicstate);     //   --extrinsicstate    减去1再传入

            Flyweight fy = f.GetFlyweight("Y");
            fy.Operation(--extrinsicstate);

            Flyweight fz = f.GetFlyweight("Z");
            fz.Operation(--extrinsicstate);

            UnsharedConcreteFlyweight uf = new UnsharedConcreteFlyweight();

            uf.Operation(--extrinsicstate);

            Console.Read();
        }
    }

    class FlyweightFactory
    {
        private Hashtable flyweights = new Hashtable();

        public FlyweightFactory()
        {
            flyweights.Add("X", new ConcreteFlyweight());
            flyweights.Add("Y", new ConcreteFlyweight());
            flyweights.Add("Z", new ConcreteFlyweight());

        }

        public Flyweight GetFlyweight(string key)
        {
            return ((Flyweight)flyweights[key]);
        }
    }

    abstract class Flyweight
    {
        public abstract void Operation(int extrinsicstate);
    }

    class ConcreteFlyweight : Flyweight
    {
        public override void Operation(int extrinsicstate)
        {
            Console.WriteLine("具体Flyweight:" + extrinsicstate);
        }
    }

    class UnsharedConcreteFlyweight : Flyweight
    {
        public override void Operation(int extrinsicstate)
        {
            Console.WriteLine("不共享的具体Flyweight:" + extrinsicstate);
        }
    }
}

四、总结

享元对象内部不会随着环境的改变而改变的共享部分可以成为享元对象的内部状态,而随着环境改变而改变的,不可以共享的状态就是外部状态了。事实上,享元模式可以避免大量的非常相似的开销,在程序设计中,有时需要生成大量细粒度的类实例来表示数据,如果发现这些实例除了几个参数不同外基本上是相同的,如果把这些参数移到类实例的外面,在方式调用时将它们传递进来,就可以通过共享大幅度减少单个实例的数目,也就是说享元模式Flyweight执行所需的状态是有内部的也有可能有外部的,内部状态存储于ConcreteFlyweight对象之中,而外部状态则应该考虑由客户端对象存储或计算,当调用Flyweight对象操作时,将该状态传递给它。
什么时候考虑使用享云模式呢?
如果一个应用程序使用了大量的对象,而大量的对象会造成很大的内存开销时就应该考虑使用,还有就是对象的大多数状态可以外部状态,如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象,此时可以考虑使用享元模式。
缺点:使用享云模式维护一个记录了系统已经有的所有享元列表,这本身也是需要耗费资源的,另外享云模式使得系统更加复杂化,为了使对象可以共享,需要将一些状态外部化,也使得程序的逻辑复杂化,因此,应当在有足够多的对象实例可共享时才值得使用享元模式。

五、另外的实例代码

namespace 享元模式
{
    public class Program
    {
        static void Main(string[] args)
        {
            GameFactory f = new GameFactory();
            AbsGame absGame1 = f.GetGame("围棋", "红色");

            AbsGame absGame2 = f.GetGame("围棋", "红色");

            AbsGame absGame3 = f.GetGame("围棋", "红色");

            AbsGame absGame4 = f.GetGame("围棋", "白色");

            AbsGame absGame5 = f.GetGame("围棋", "白色");

            AbsGame absGame6 = f.GetGame("飞机棋", "红色");
            AbsGame absGame7 = f.GetGame("飞机棋", "红色");
            AbsGame absGame8 = f.GetGame("飞机棋", "红色");
            AbsGame absGame9 = f.GetGame("飞机棋", "白色");
            AbsGame absGame10 = f.GetGame("飞机棋", "白色");
            AbsGame absGame11 = f.GetGame("飞机棋", "黄色");
            AbsGame absGame12 = f.GetGame("飞机棋", "蓝色");

            f.CountGame();

            absGame1.Show(1);
            absGame2.Show(2);
            absGame3.Show(3);
            absGame4.Show(4);
            absGame5.Show(5);
            absGame6.Show(6);
            absGame7.Show(7);
            absGame8.Show(8);
            absGame9.Show(9);
            absGame10.Show(10);
            absGame11.Show(11);
            absGame12.Show(12);

            Console.WriteLine("------------------------围棋2种棋子啦啦啦啦啦啦----------------");

            Console.WriteLine("------------------------飞机棋4种棋子啦啦啦啦啦啦----------------");

            absGame1.GetChess("红色").Color();
            absGame4.GetChess("白色").Color();

            absGame5.GetChess("红色").Color();

            Console.WriteLine("围棋的棋子实例个数=" + ((Game)absGame3).htChess.Count);

            Console.WriteLine("飞机棋的棋子实例个数=" + ((Game)absGame10).htChess.Count);

            //absGame3.CountChess();
            //absGame10.CountChess();

            Console.ReadKey();

        }
    }

    public class GameFactory
    {
        public Hashtable htGame = new Hashtable();

        public AbsGame GetGame(string gameName, string color)
        {

            if (((Game)htGame[gameName]) == null)
            {
                htGame.Add(gameName, new Game(gameName, color));
            }

            if ((htGame.ContainsKey(gameName)) && !((Game)htGame[gameName]).htChess.ContainsKey(color))
            {
                ((Game)htGame[gameName]).GetChess(color);
            }
            return (Game)htGame[gameName];
        }

        public void CountGame()
        {
            Console.WriteLine("一共有" + htGame.Count + "个游戏对象");
        }

    }

    public abstract class AbsGame
    {
        public abstract void Show(int index);
        public abstract AbsChess GetChess(string color);
        public abstract void CountChess();
    }

    public class Game : AbsGame
    {

        public string GameName;

        public Hashtable htChess = new Hashtable();

        public Game(string gameName, string color)
        {

            GameName = gameName;
            GetChess(color);
        }

        public override AbsChess GetChess(string color)
        {
            if (!htChess.ContainsKey(color))
            {
                htChess.Add(color, new Chess(color));
            }
            return (Chess)htChess[color];
        }

        public override void Show(int index)
        {
            Console.WriteLine("游戏名:" + GameName + ",下棋位置:" + index);
        }

        public override void CountChess()
        {
            Console.WriteLine("一共有" + htChess.Count + "个棋子对象");
        }

    }

    public abstract class AbsChess
    {

        public abstract void Color();
    }

    public class Chess : AbsChess
    {
        private string color;
        public Chess(string color)
        {
            this.color = color;
        }
        public override void Color()
        {
            Console.WriteLine("这是" + color + "棋子");
        }
    }
}
时间: 2024-08-06 11:58:16

C#面向对象设计之——享元模式(十二)的相关文章

java设计优化-享元模式

享元模式是设计模式中少数几个以调高系统性能为目的的设计模式.它的核心思想是:如果在一个系统中存在多个相同的对象,那么只需共享一份对象的拷贝,而不必为每一次使用都创建新的对象.在享元模式中,由于需要构建和维护这些可以共享的对象,因此,常常会出现一个工厂类,用于维护和创建对象. 享元模式对性能提升的主要帮助有两点: 1.可以节省重复创建对象的开销,因为被享元模式维护的相同对象只会被创建一次,当对象创建比较耗时时,便可以节省大量时间: 2.由于创建对象的数量减少,所有对系统内存的需求也减少,这样使GC

C#面向对象设计之——策略者模式(二十)

一.前言 策略模式定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户. 二.结构图 三.实例代码 using System; using System.Collections.Generic; using System.Text; namespace 策略模式 { class Program { static void Main(string[] args) { Context context; context = new Context(new

C#面向对象设计之——简单工厂模式(二)

一.前言 简单工厂是一个负责生产对象的中间类,例如有加减乘除四个运算方法,它们继承父类,并重写父类的方法,简单工厂根据不同的运算符创建不同的实例对象赋值给父类,实现了面向对象的另一个原则——降低对象之间的耦合度.简单工厂模式解决了客户端直接依赖于具体对象的问题,客户端可以消除直接创建对象的责任,而仅仅是消费产品.简单工厂模式实现了对责任的分割. 简单工厂模式的缺点: 工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都会受到影响 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,这样就会造

【转】享元模式——实现对象的复用

[作者:刘伟  http://blog.csdn.net/lovelion] 当前咱们国家正在大力倡导构建和谐社会,其中一个很重要的组成部分就是建设资源节约型社会,“浪费可耻,节俭光荣”.在软件系统中,有时候也会存在资源浪费的情况,例如在计算机内存中存储了多个完全相同或者非常相似的对象,如果这些对象的数量太多将导致系统运行代价过高,内存属于计算机的“稀缺资源”,不应该用来“随便浪费”,那么是否存在一种技术可以用于节约内存使用空间,实现对这些相同或者相似对象的共享访问呢?答案是肯定,这种技术就是我

设计模式——12.享元模式

1. 模式动机 面向对象技术可以很好地解决一些灵活性或可扩展性问题,但在很多情况下需要在系统中增加类和对象的个数.当对象数量太多时,将导致运行代价过高,带来性能下降等问题. 享元模式正是为解决这一类问题而诞生的.享元模式通过共享技术实现相同或相似对象的重用. 在享元模式中可以共享的相同内容称为内部状态(IntrinsicState),而那些需要外部环境来设置的不能共享的内容称为外部状态(Extrinsic State),由于区分了内部状态和外部状态,因此可以通过设置不同的外部状态使得相同的对象可

设计模式(十二): Flyweight享元模式 -- 结构型模式

说明: 相对于其它模式,Flyweight模式在PHP实现似乎没有太大的意义,因为PHP的生命周期就在一个请求,请求执行完了,php占用的资源都被释放.我们只是为了学习而简单做了介绍. 1. 概述 面向对象技术可以很好地解决系统一些灵活性或可扩展性或抽象性的问题,但在很多情况下需要在系统中增加类和对象的个数.当对象数量太多时,将导致运行代价过高,带来性能下降等问题.比如:例子1:图形应用中的图元等对象.字处理应用中的字符对象等. 2.解决方案: 享元模式(Flyweight):对象结构型模式运用

设计模式(十)享元模式Flyweight(结构型)

说明: 相对于其它模式,Flyweight模式在PHP实现似乎没有太大的意义,因为PHP的生命周期就在一个请求,请求执行完了,php占用的资源都被释放.我们只是为了学习而简单做了介绍. 1. 概述 面向对象技术可以很好地解决系统一些灵活性或可扩展性或抽象性的问题,但在很多情况下需要在系统中增加类和对象的个数.当对象数量太多时,将导致运行代价过高,带来性能下降等问题.比如:例子1:图形应用中的图元等对象.字处理应用中的字符对象等. 2.解决方案: 享元模式(Flyweight):对象结构型模式运用

设计模式(十二)—— 享元模式

模式简介 运用共享技术有效地支持大量细粒度地对象. 通常情况下,面向对象技术可以增强系统地灵活性及可扩展性,在系统开发过程中,我们会不断地增加类和对象.当对象数量过多时,将会带来系统开销过高.性能下降等问题.享元模式通过共享相同或相似的对象来解决这一类问题.在介绍享元模式之前,首先要弄清楚两个概念:内部状态(Intrinsic State)和外部状态(Extrinsic State). 内部状态是存储在享元对象内部并且不会随环境改变而改变的状态,因此内部状态可以共享.例如,围棋中的棋子,它们的形

设计模式(十二)享元模式(Flyweight Pattern)

一.引言 在软件开发过程,如果我们需要重复使用某个对象的时候,如果我们重复地使用new创建这个对象的话,这样我们在内存就需要多次地去申请内存空间了,这样可能会出现内存使用越来越多的情况,这样的问题是非常严重,然而享元模式可以解决这个问题,下面具体看看享元模式是如何去解决这个问题的. 二.享元模式的详细介绍 在前面说了,享元模式可以解决上面的问题了,在介绍享元模式之前,让我们先要分析下如果去解决上面那个问题,上面的问题就是重复创建了同一个对象,如果让我们去解决这个问题肯定会这样想:“既然都是同一个