抽象工厂
对比抽象工厂和工厂方法
工厂方法中,有一个抽象产品和一个抽象工厂,然后具体产品由具体工厂来生产
抽象工厂中,有多个抽象产品,一个抽象工厂,然后多个具体工厂都能生产这两类产品,只不过生产出来的具体产品并不相同
举例来说:
苹果和小米都生产手机、平板、电脑,他们是两家具体的工厂,都生产这三个等级的产品
苹果、小米各都是一个产品族
我们三个抽象产品,分别是手机、平板、电脑
我们有一个抽象工厂,可以生产这三类产品
我们有两个具体工厂,分别是苹果,小米
他们生产的具体产品是
苹果手机、苹果电脑、苹果平板
小米手机、小米电脑、小米平板
这就是抽象工厂
UML图例
代码
抽象类, 抽象 Phone、Pad, 抽象工厂
namespace DesignModel.AbstractFactory
{
//phone接口
public interface IPhone
{
void Show();
}
//pad接口
public interface IPad
{
void Show();
}
//抽象工厂接口
public interface IFactory
{
IPhone CreatePhone();
IPad CreatePad();
}
}
Apple产品族
namespace DesignModel.AbstractFactory
{
public class ApplePad : IPad
{
public void Show()
{
Debug.Log("Show: Apple Pad");
}
}
public class ApplePhone : IPhone
{
public void Show()
{
Debug.Log("Show: Apple Phone");
}
}
}
Mi产品族
namespace DesignModel.AbstractFactory
{
public class MiPhone : IPhone
{
public void Show()
{
Debug.Log("Show: Mi Phone");
}
}
public class MiPad : IPad
{
public void Show()
{
Debug.Log("Show: Mi Pad");
}
}
}
App工厂和Mi工厂
namespace DesignModel.AbstractFactory
{
public class AppleFactory : IFactory
{
public IPad CreatePad()
{
return new ApplePad();
}
public IPhone CreatePhone()
{
return new ApplePhone();
}
}
public class MiFactory : IFactory
{
public IPad CreatePad()
{
return new MiPad();
}
public IPhone CreatePhone()
{
return new MiPhone();
}
}
}
Client
using DesignModel.AbstractFactory;
public class AbstractFactoryClient : MonoBehaviour
{
void Start ()
{
IFactory appleFactory = new AppleFactory();
IFactory miFactory = new MiFactory();
var miPad = miFactory.CreatePad();
var miPhone = miFactory.CreatePhone();
miPad.Show();
miPhone.Show();
var ipad = appleFactory.CreatePad();
var iphone = appleFactory.CreatePhone();
ipad.Show();
iphone.Show();
}
}
抽象工厂局限
工厂方法和抽象工厂,在我理解的意义就是,
通过工厂方法,可以方便的拓展具体产品种类
而通过抽象工厂,可以方便的拓展和修改产品族
客户不需要知道具体要创建的产品,只需要知道创建产品的工厂就行了,这样对于使用一个产品类族的客户来说,可以保证他使用的是同一个产品类族
抽象工厂的缺点:
拓展抽象产品类型会很麻烦,需要修改所有的具体工厂
而在工厂方法中,因为每个具体工厂只生产一种具体的产品,则没有这个缺点,但一个工厂方法只能生产一类抽象产品
拓展
依然将抽象工厂放到对象池中
首先定义一个获取类型的接口
namespace DesignModel.AbstractFactory
{
public enum FactoryType
{
Apple = 1,
Mi = 2
}
public interface IFactoryType
{
FactoryType GetFactoryType();
}
}
修改各个产品的实现
namespace DesignModel.AbstractFactory
{
//Apple产品族
public class ApplePad : IPad , IFactoryType
{
public ApplePad()
{
Debug.Log("Create: Apple Pad");
}
public void Show()
{
Debug.Log("Show: Apple Pad");
}
public FactoryType GetFactoryType()
{
return FactoryType.Apple;
}
}
public class ApplePhone : IPhone , IFactoryType
{
public ApplePhone()
{
Debug.Log("Create: Apple Phone");
}
public void Show()
{
Debug.Log("Show: Apple Phone");
}
public FactoryType GetFactoryType()
{
return FactoryType.Apple;
}
}
//Mi产品族
public class MiPad : IPad , IFactoryType
{
public MiPad()
{
Debug.Log("Create: Mi Pad");
}
public void Show()
{
Debug.Log("Show: Mi Pad");
}
public FactoryType GetFactoryType()
{
return FactoryType.Mi;
}
}
public class MiPhone : IPhone , IFactoryType
{
public MiPhone()
{
Debug.Log("Create: Mi Phone");
}
public void Show()
{
Debug.Log("Show: Mi Phone");
}
public FactoryType GetFactoryType()
{
return FactoryType.Mi;
}
}
}
实现我们的对象池
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace DesignModel.AbstractFactory
{
public class AFPoolManager
{
//单例
private static AFPoolManager instance = null;
public static AFPoolManager Instance
{
get
{
if (instance == null) instance = new AFPoolManager();
return instance;
}
}
//对象池
private Dictionary<FactoryType,List<IPad>> padPool;
private Dictionary<FactoryType,List<IPhone>> phonePool;
//私有化初始化,并填充对象池类型
private AFPoolManager()
{
padPool = new Dictionary<FactoryType, List<IPad>>();
padPool.Add(FactoryType.Apple, new List<IPad>());
padPool.Add(FactoryType.Mi, new List<IPad>());
phonePool = new Dictionary<FactoryType, List<IPhone>>();
phonePool.Add(FactoryType.Apple, new List<IPhone>());
phonePool.Add(FactoryType.Mi, new List<IPhone>());
}
/// <summary>
/// 根据指定工厂 获取Pad
/// </summary>
/// <param name="factoryType">指定工厂</param>
public IPad GetPad(FactoryType factoryType)
{
IPad pad = null;
if (padPool[factoryType].Count > 0)
{
pad = padPool[factoryType][0];
padPool[factoryType].RemoveAt(0);
}
else
{
pad = CreatePad(factoryType);
}
return pad;
}
private IPad CreatePad(FactoryType factoryType)
{
switch (factoryType)
{
case FactoryType.Apple:
return new AppleFactory().CreatePad();
case FactoryType.Mi:
return new MiFactory().CreatePad();
default:
return null;
}
}
/// <summary>
/// 根据指定工厂 获取Phone
/// </summary>
/// <param name="factoryType">指定工厂</param>
public IPhone GetPhone(FactoryType factoryType)
{
IPhone phone = null;
if (phonePool[factoryType].Count > 0)
{
phone = phonePool[factoryType][0];
phonePool[factoryType].RemoveAt(0);
}
else
{
phone = CreatePhone(factoryType);
}
return phone;
}
private IPhone CreatePhone(FactoryType factoryType)
{
switch (factoryType)
{
case FactoryType.Apple:
return new AppleFactory().CreatePhone();
case FactoryType.Mi:
return new MiFactory().CreatePhone();
default:
return null;
}
}
/// <summary>
/// 回收Pad
/// </summary>
/// <param name="item"></param>
public void RecoverProduct(IPad item)
{
if (padPool.ContainsKey(((IFactoryType)item).GetFactoryType()))
padPool[((IFactoryType)item).GetFactoryType()].Add(item);
}
/// <summary>
/// 回收Phone
/// </summary>
/// <param name="item"></param>
public void RecoverProduct(IPhone item)
{
if (phonePool.ContainsKey(((IFactoryType)item).GetFactoryType()))
phonePool[((IFactoryType)item).GetFactoryType()].Add(item);
}
}
}
可以看到,我们获取对象需要指定对应的产品族工厂,但不需要知道具体的产品类型,而在回收对象时,我们通过另一个接口实现了对对象的回收。
简单的测试代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DesignModel.AbstractFactory;
public class AbstractFactoryClient : MonoBehaviour
{
void Start ()
{
var miPad2 = AFPoolManager.Instance.GetPad(FactoryType.Mi);
miPad2.Show();
AFPoolManager.Instance.RecoverProduct(miPad2);
var iphone2 = AFPoolManager.Instance.GetPhone(FactoryType.Apple);
iphone2.Show();
AFPoolManager.Instance.RecoverProduct(iphone2);
var miPad3 = AFPoolManager.Instance.GetPad(FactoryType.Mi);
miPad3.Show();
AFPoolManager.Instance.RecoverProduct(miPad3);
}
}
测试结果