设计模式-结构型-享元模式

设计模式-结构型-享元模式(缓存模式,Cache,Flyweight)

通过共享多个对象所共有的相同状态, 使有限的内存容量中载入更多对象。



前言

基于面向对象编程的思想,当系统中的类和对象的个数太多时,导致大量性能被损耗,享元模式可以解决性能下降的问题。


一、享元模式(缓存共享对象,降低内存消耗)

享元模式(轻量级模式),是对象池的一种实现,类似于线程池(线程池可以避免不停的创建和销毁对象的性能损耗),享元模式通过减少对象数量,达到改善应用所需的对象结构的方式,减少性能损耗。
享元模式将对象的状态分为(内部状态:对象内部状态是稳定不变的)和(外部状态:对象外部状态是可变化的),通过共享内部状态达到减少对象数量节约内存的目的。

二、应用场景

  • 常应用与系统底层的开发,以解决系统性能的问题
  • 系统有大量相似对象,需要缓冲池的场景

三、角色

  • 抽象享元角色(IFlyweight): 享元对象的抽象基类或接口,定义对象内部及外部状态的抽象。
  • 具体享元角色(ConcreteFlyweight):实现抽象享元角色定义的业务。
  • 享元工厂(FlyweightFactory):管理享元对象池和创建享元对象

四、使用步骤

1.抽象享元

代码如下(示例):抽象享元方法

 	/// <summary>
    /// 抽象享元
    /// </summary>
    public interface IFlyweight
    {
        void operation(string extrinsicState);
    }

2.具体享元

代码如下(示例):完成具体享元实现

 	/// <summary>
    /// 具体享元
    /// </summary>
    public class ConcreteFlyweight : IFlyweight
    {
        private string intrinsicState;
        public ConcreteFlyweight(string str)
        {
            this.intrinsicState = str;
        }
        public void operation(string extrinsicState)
        {
            Console.WriteLine($"Object address:{this.intrinsicState.GetHashCode()}");
            Console.WriteLine($"intrinsicState:{this.intrinsicState}");
            Console.WriteLine($"str:{extrinsicState}");
        }
    }

3.创建享元工厂(重点)

代码如下(示例):享元工厂,定义享元对象池

 	/// <summary>
    /// 享元工厂(创建对象)
    /// </summary>
    public class FlyweightFactory
    {
        private static Dictionary<string, IFlyweight> pool = new Dictionary<string, IFlyweight>();
        /// <summary>
        /// 获取IFlyweight的对象
        /// </summary>
        /// <param name="intrinsicState"></param>
        /// <returns></returns>
        public IFlyweight getFlyweight(string intrinsicState)
        {
            if (!pool.ContainsKey(intrinsicState))
            {
                Console.WriteLine($"Dictionary 不包含 key 为{intrinsicState} 的 IFlyweight 对象");
                IFlyweight fw = new ConcreteFlyweight(intrinsicState);
                pool.Add(intrinsicState, fw);
            }
            else
            {
                Console.WriteLine($"Dictionary 包含 key 为{intrinsicState} 的 IFlyweight 对象,开始去查询");
            }
            return pool.Where(p => p.Key.Equals(intrinsicState)).FirstOrDefault().Value;
        }

    }

4.客户端调用

代码如下(示例):

	/// <summary>
    /// 享元调用者
    /// </summary>
    public class FlyweightClient
    {
        public void client()
        {
            FlyweightFactory ff = new FlyweightFactory();
            IFlyweight ifw = ff.getFlyweight("aa");
            IFlyweight ifws = ff.getFlyweight("aa");
            IFlyweight ifw2 = ff.getFlyweight("abb");
            ifw.operation("a");
            ifws.operation("a");
            ifw2.operation("b");
        }
    }

5.Run 结果

代码如下(示例):

享元模式
Dictionary 不包含 key 为aa 的 IFlyweight 对象
Dictionary 包含 key 为aa 的 IFlyweight 对象,开始去查询
Dictionary 不包含 key 为abb 的 IFlyweight 对象
Object address:-630000639
intrinsicState:aa
str:a
Object address:-630000639
intrinsicState:aa
str:a
Object address:1214818789
intrinsicState:abb
str:b

该处使用的url网络请求的数据。


总结

优点

  • 有效的减少了对象的创建(享元对象池),降低了内存中对象的数量,降低了系统的内存,提供效率。
  • 减少对象的创建,导致内存之外的其他资源占用也被降低。

缺点

  • 关注内部,外部状态,关注线程安全问题
  • 使用系统,程序的逻辑复杂化。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kenny@chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值