简单工厂

16 篇文章 0 订阅
1 篇文章 0 订阅

简单工厂

简单工厂的意义在于,将子类的创建放在工厂中一起创建,防止子类拓展或修改后,对上层调用的影响

没有工厂的情况

假设我们知道手机这个类,以及它的子类iPhoneXs、VivoPhone
在这里插入图片描述

public class PhoneBase 
{
	public virtual void Show()
    {
        Debug.Log("My Phone Name : ");
    }
    public virtual void Check()
    {
        Debug.Log("Check Phone Name : ");
    }
}

public class iPhoneXs : PhoneBase {

	public override void Show()
	{
		base.Show();
		Debug.Log("iPhone Xs");
	}
    public override void Check()
	{
		base.Check();
		Debug.Log("iPhone Xs");
	}
}

public class VivoPhone : PhoneBase 
{
	public override void Show()
	{
		base.Show();
		Debug.Log("Vivo");
	}
	public override void Check()
	{
		base.Check();
		Debug.Log("Vivo");
	}
}

我们有Clinet1运营商,他要负责展示手机,Client2维修部,负责检查手机

public enum PhoneType
{
	iPhoneXs = 1,
	VivoPhone = 2
}

public class Clinet_1
{
	public void ShowPhone(PhoneType type)
	{
		PhoneBase phone = null;
		switch(type)
		{
			case PhoneType.iPhoneXs:
				phone = new iPhoneXs();
			break;
			case PhoneType.VivoPhone:
				phone = new VivoPhone();
			break;
		}

		if (phone != null) 
			phone.Show();
	}
}

public class Clinet_2
{
	public void CheckPhone(PhoneType type)
	{
		PhoneBase phone = null;
		switch(type)
		{
			case PhoneType.iPhoneXs:
				phone = new iPhoneXs();
			break;
			case PhoneType.VivoPhone:
				phone = new VivoPhone();
			break;
		}

		if (phone != null) 
			phone.Check();
	}
}

此时新增手机类型Mi Phone,则需要同时改动Client1和Client2,如果我有更多的Client,那么要改动的地方会更多

添加简单工厂

在PhoneBase的基础上,我们添加一个Phone工厂,用于获取手机对象
在这里插入图片描述

public class PhoneFactory  
{
	public enum PhoneType
	{
		iPhoneXs = 1,
		VivoPhone = 2
	}
	public static PhoneBase CreatePhone(PhoneType type)
	{
		switch(type)
		{
			case PhoneType.iPhoneXs:
				return new iPhoneXs();
			case PhoneType.VivoPhone:
				return new VivoPhone();
		}
		return null;
	}
}

对于之前的两个Client,可以修改为:

public class Clinet_1
{
	public void ShowPhone(PhoneFactory.PhoneType type)
	{
		PhoneBase phone = PhoneFactory.CreatePhone(type);

		if (phone != null) 
			phone.Show();
	}
}

public class Clinet_2
{
	public void CheckPhone(PhoneFactory.PhoneType type)
	{
		PhoneBase phone = PhoneFactory.CreatePhone(type);

		if (phone != null) 
			phone.Check();
	}
}

当我们新增Mi Phone,则只需要改动简单工厂,而无需修改Client

拓展

实际应用中,工厂类可以作为对象池或与对象池一起工作,在Unity中,可以通过工厂模式和对象池来做资源管理

public class PhonePoolManager
{
	//单例
	private static PhonePoolManager instance = null;
	public static PhonePoolManager Instance
	{
		get
		{
			if (instance == null) instance = new PhonePoolManager();
			return instance;
		}
	}
	
	//对象池
	private Dictionary<PhoneFactory.PhoneType,List<PhoneBase>> pool;
	//私有化初始化,并填充对象池类型
	private PhonePoolManager()
	{
		pool = new Dictionary<PhoneFactory.PhoneType, List<PhoneBase>>();
		pool.Add(PhoneFactory.PhoneType.iPhoneXs, new List<PhoneBase>());
		pool.Add(PhoneFactory.PhoneType.VivoPhone, new List<PhoneBase>());
	}

	/// <summary>
	/// 获取Phone对象
	/// </summary>
	/// <param name="type">要获取的对象类型</param>
	public PhoneBase GetPhone(PhoneFactory.PhoneType type)
	{
		PhoneBase phone = null;
		if (pool[type].Count <= 0)
			phone = PhoneFactory.CreatePhone(type);
		else
		{
			phone = pool[type][0];
			pool[type].RemoveAt(0);
		}
		return phone;
	}


	/// <summary>
	/// 回收phone对象
	/// </summary>
	/// <param name="item">要回收的对象</param>
	public void RecoverPhone(PhoneBase item)
	{
		switch(item.GetPhoneType())
		{
			case PhoneFactory.PhoneType.VivoPhone:
				pool[PhoneFactory.PhoneType.VivoPhone].Add(item);
			break;
			case PhoneFactory.PhoneType.iPhoneXs:
				pool[PhoneFactory.PhoneType.iPhoneXs].Add(item);
			break;
		}
	}
}

此时我们的Client通过对象池获取对象

public class Clinet_1
{
	public void ShowPhone(PhoneFactory.PhoneType type)
	{
		PhoneBase phone = PhonePoolManager.Instance.GetPhone(type);

		if (phone != null) 
			phone.Show();
        
        //使用完后记得回收
        PhonePoolManager.Instance.RecoverPhone(phone);、
	}
}

使用对象池可以减少频繁创建对象造成的性能问题,更复杂一些的对象池还会按对象使用频次释放销毁低频对像,以优化内存占用

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值