享元模式

享元模式

定义

享元模式(Flyweight)

​ 运用共享技术有效地支持大量细粒度的对象。

解释:

​ 大量的对象会出现两个问题:1.内存的大量占用;2.大量对象的创建和销毁时间;

​ 享元模式就是用一种方法去共享“元件”,以减少内存占用和对象数量

UML

在这里插入图片描述

成员

在享元模式中,我们将对象成员分为:

​ 1.内在状态 由享元对象自己保存内部状态

​ 2.外在状态 可以动态改变,享元对象需要用到外部状态的方法,在使用时由参数传递对应的外部状态

例如:我们有一个抽象角色类,而士兵类继承自角色类

​ 每个士兵对象都有共同的属性,例如最大生命值、衣着(材质)、速度等,这些属于士兵的内在状态;

​ 每个士兵都有自己的独有的属性,例如位置、血量等,这些属于士兵的外在状态;

享元对象抽象(Flyweight):保存内在状态,并在需要时提供方法以参数的形式使用外部状态;

享元对象实现(FlyweightConcrete):继承自享元对象抽象,并实现相应的方法,保存内在状态

享元对象工厂(FlyweightFactory):以对象池的方式,创建并提供享元对象

代码

享元对象抽象及实现

namespace DesignModel.Flyweight
{
	//享元对象抽象
	public abstract class Flyweight 
	{
		protected string intrinsic;		//内部状态
		public Flyweight(string intrinsic)
		{
			this.intrinsic = intrinsic;
		}
		public abstract void Operate(string extrinsic);		//操作 传入外部状态
	}
    
    //享元对象实现
    public class FlyweightConcrete : Flyweight 
	{
		public FlyweightConcrete(string intrinsic): base(intrinsic){}

		public override void Operate(string extrinsic)
		{
			Debug.Log("享元对象操作:");
			Debug.Log("    内部状态: " + intrinsic);
			Debug.Log("    外部状态: " + extrinsic);
		}
	}
}

享元对象工厂

namespace DesignModel.Flyweight
{
	public class FlyweightConst
	{
		public const string A = "A";
		public const string B = "B";
		public const string C = "C";
	}
	public class FlyweightFactory 
	{
		private Dictionary<string, Flyweight> flyweightDic;
		public FlyweightFactory()
		{
			flyweightDic = new Dictionary<string, Flyweight>();

			flyweightDic.Add(FlyweightConst.A, new FlyweightConcrete(FlyweightConst.A));
			flyweightDic.Add(FlyweightConst.B, new FlyweightConcrete(FlyweightConst.B));
			flyweightDic.Add(FlyweightConst.C, new FlyweightConcrete(FlyweightConst.C));
		}
		public Flyweight GetFlyweight(string type)
		{
			if (!flyweightDic.ContainsKey(type))
			{
				flyweightDic.Add(type, new FlyweightConcrete(type));
			}
			return flyweightDic[type];
		}
	}
}

简单测试

using DesignModel.Flyweight;
public class Client_Flyewight : MonoBehaviour 
{
	void Start () 
	{
		FlyweightFactory factory = new FlyweightFactory();
		string testX = "testX";
		string testY = "testY";

		Flyweight f1 = factory.GetFlyweight(FlyweightConst.A);
		//一个享元对象使用相同的内部变量 使用不同的外部变量
		f1.Operate(testX);
		f1.Operate(testY);

		Flyweight f2 = factory.GetFlyweight(FlyweightConst.B);
		f2.Operate(testX);

		Flyweight f3 = factory.GetFlyweight("test");
		f3.Operate("zzz");
	}
}

测试结果
在这里插入图片描述

享元模式应用

优点:

​ 1.将对象的内在成员共享,达到了减少内存占用的目的;

​ 2.使用对象池创建获取内在成员,减少了大量成员的创建和销毁的性能消耗;

缺点:

​ 1.需要将成员区分为内在状态和外在状态,对象系统变得复杂化

应用场景

​ 1.系统中有大量对象

​ 2.对象数量导致了内存大量内存占用和创建成本

​ 3.这些对象有共同的不变的特征

拓展

在实际应用中,对象池技术就是利用了享元模式的思想,但对象池和享元模式侧重点有所差别

对象池和享元的相同是

​ 1. 都解决了对象的复用

对象池和享元不同的是

​ 1. 对象池中可能会有完全相同的对象,而享元模式中则不会有完全相同的对象

​ 2. 对象池的着力点在于对象的复用,以减少重复创建和销毁

​ 享元模式的着力点在于内在状态的复用,以减少内存占用

​ 二者其实并不冲突

​ 3. 对象池有对象回收,享元模式不需要回收,因为每次派发出去的是同一个对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值