设计模式------享元模式(Flyweight)

享元模式在编辑器系统中大量的使用

享元模式以共享的方式高效的支持大量的细粒度对象。

享元对象能够做到共享的关键是区分内部状态(Internal State)外部状态(External State)

内部状态是存储在享元对象内部并且不会随环境改变而改变。因此内部状态可以共享。

外部状态是随环境改变而改变的、不可以共享的状态。享元对象的外部状态必须由客户端保存,并且在享元对象被创建之后,在需要使用的时候再传入到享元对象的内部。

外部状态与内部状态是相互独立的。

享元模式设计的重点就在分离变与不变。把一个对象的状态分成内部状态和外部状态,内部状态是不变的,外部状态是可变的。然后通过共享不变的部分,达到减少对象数量并节约内存的目的。

分离变与不变是软件设计上最基本的方式之一,比如预留接口:一个常见的原因就是这里存在变化,可能在今后需要去扩展或者是改变已有的实现,因此预留接口作为“可插入性的保证”。

1、享元模式的本质:分离与共享

2、享元模式的优缺点:

优点:大幅度地降低内存中对象的数量,节省内存空间。

缺点:

(1)享元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。

(2)享元模式将享元对象的状态外部化,而读取外部状态使得运行时间变长。

3、在什么情况下(或满足哪些条件)使用享元模式:

(1)一个系统有大量对象

(2)这些对象耗费大量的内存

(3)这些对象的状态中的大部分都可以外部化

(4)这些对象可以按照内部状态分成很多组,当把外部对象从对象中剔除时,每一个组都可以仅用一个对象代替。

注意:使用享元模式需要维护一个记录了系统已有的所有享元的表,而这需要耗费资源。因此,应当在有足够多的享元实例可供共享时才值得使用享元模式。

享元模式模拟实现五子棋

UML图:

代码如下:

namespace 五子棋_享元模式
{
    abstract class AbstractChess
    {
        public abstract void play(Chess c);
    }
}


namespace 五子棋_享元模式
{
    class WhiteChess:AbstractChess
    {
        public override void play(Chess c)
        {
            Console.WriteLine("白子:" + "(" + c.X + "," + c.Y + ")");
        }
    }
}


namespace 五子棋_享元模式
{
    class BlackChess:AbstractChess
    {
        public override void play(Chess c)
        {
            Console.WriteLine("黑子:" + "("+c.X + "," + c.Y + ")");
        }
    }
}


namespace 五子棋_享元模式
{
    class ChessFactory
    {
        private Hashtable flyweights = new Hashtable();
        public ChessFactory()
        {
            flyweights.Add("B", new BlackChess());
            flyweights.Add("W", new WhiteChess());
        }
        public AbstractChess GetChess(string key)
        {
            return ((AbstractChess)flyweights[key]);
        }
    }
}


namespace 五子棋_享元模式
{
    class Chess
    {
        private int x;
        private int y;
        public Chess() { }
        public Chess(int x, int y)
        {
            this.x = x;
            this.y = y;
        }

        public int X { get => x; set => x = value; }
        public int Y { get => y; set => y = value; }
    }
}


namespace 五子棋_享元模式
{
    class Program
    {
        static void Main(string[] args)
        {
            Chess c1 = new Chess(1, 1);
            Chess c2 = new Chess(2, 4);
            ChessFactory cf = new ChessFactory();
            AbstractChess cf1 = cf.GetChess("B");
            cf1.play(c1);
            AbstractChess cf2 = cf.GetChess("W");
            cf2.play(c2);
            c1.X = 3;
            c1.Y = 4;
            cf1.play(c1);
            
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值