抽象工厂

抽象工厂

对比抽象工厂和工厂方法

工厂方法中,有一个抽象产品和一个抽象工厂,然后具体产品由具体工厂来生产

抽象工厂中,有多个抽象产品,一个抽象工厂,然后多个具体工厂都能生产这两类产品,只不过生产出来的具体产品并不相同

举例来说:

​ 苹果和小米都生产手机、平板、电脑,他们是两家具体的工厂,都生产这三个等级的产品

​ 苹果、小米各都是一个产品族

​ 我们三个抽象产品,分别是手机、平板、电脑

​ 我们有一个抽象工厂,可以生产这三类产品
​ 我们有两个具体工厂,分别是苹果,小米

​ 他们生产的具体产品是

​ 苹果手机、苹果电脑、苹果平板

​ 小米手机、小米电脑、小米平板

这就是抽象工厂

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);
	}
}

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值