简单工厂
简单工厂的意义在于,将子类的创建放在工厂中一起创建,防止子类拓展或修改后,对上层调用的影响
没有工厂的情况
假设我们知道手机这个类,以及它的子类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);、
}
}
使用对象池可以减少频繁创建对象造成的性能问题,更复杂一些的对象池还会按对象使用频次释放销毁低频对像,以优化内存占用