抽象工厂模式
抽象工厂模式能创建一系列相关的产品,而无需指定具体类。
抽象工厂所生产的不是某一类产品,而是一系列,相当于一个组合套装,这些产品是捆绑的。
比方说,买装台式机,我们可以选择 显卡,CPU,主板,内存条等。他们是一系列相关产品。买一套衣服,一般都是上衣和裤子,作为一套直接卖,裤子和上衣就是相关的系列产品。
所以,我们需要有一个初步概念,抽象工厂只生产一系列相关的产品,而非一种,如果想只生产一种的话,应该使用工厂方法模式。
结构
抽象工厂模式定义 抽象工厂接口 ,抽象产品,具体工厂,具体产品
- 抽象工厂 - 规定子工厂实现的系列产品有哪些,本身也可以编写一些核心逻辑
- 抽象产品 - 规定了子产品的功能
- 具体工厂 - 实现相关创建
- 具体产品 - 实现相关功能
实现 - Unity
我们举一个 剑盾工厂 的例子
此工厂只生产 剑和盾 的组合产品
产品
剑
public interface ISword
{
string Name { get; }
void Attack();
}
public class FlameSword : ISword
{
public string Name => "火焰剑";
public void Attack()
{
Debug.Log(Name + "发起火属性攻击");
}
}
public class WaterSword : ISword
{
public string Name => "流水剑";
public void Attack()
{
Debug.Log(Name + "发出水属性攻击");
}
}
盾
public interface IShield
{
string Name { get; }
void Defense();
}
public class FlameShield : IShield
{
public string Name => "防火盾";
public void Defense()
{
Debug.Log("防止火属性攻击");
}
}
public class WaterShield : IShield
{
public string Name => "防水盾";
public void Defense()
{
Debug.Log("防止水属性攻击");
}
}
工厂
public abstract class SwordAndShieldFactory
{
public abstract ISword CreateSword();
public abstract IShield CreateShield();
public (ISword sword, IShield shield) CreateSwordAndShield() => (CreateSword(), CreateShield());
}
public class FlameWeaponFactory : SwordAndShieldFactory
{
public override IShield CreateShield()
{
return new FlameShield();
}
public override ISword CreateSword()
{
return new FlameSword();
}
}
public class WaterWeaponFactory : SwordAndShieldFactory
{
public override IShield CreateShield()
{
return new WaterShield();
}
public override ISword CreateSword()
{
return new WaterSword();
}
}
调用
public class AbstractFactoryExample : MonoBehaviour
{
void Start()
{
SwordAndShieldFactory[] arr = new SwordAndShieldFactory[2];
arr[0] = new FlameWeaponFactory();
arr[1] = new WaterWeaponFactory();
var swordAndShield1 = arr[0].CreateSwordAndShield();
Debug.Log(swordAndShield1.sword.Name);
swordAndShield1.sword.Attack();
Debug.Log(swordAndShield1.shield.Name);
swordAndShield1.shield.Defense();
var swordAndShield2 = arr[1].CreateSwordAndShield();
Debug.Log(swordAndShield2.sword.Name);
swordAndShield2.sword.Attack();
Debug.Log(swordAndShield2.shield.Name);
swordAndShield2.shield.Defense();
}
}
应用场景
当代码需要多个不同产品交互时,并且出于对未来扩展性的考虑,我们可以需将 创建 和 使用分离,防止调用端的创建,可以使用抽象工厂模式。
利与弊
优点
- 确保工厂生产的产品相互关联
- 避免客户端创建具体产品,降低耦合度
- 每个产品只需关注实现,工厂关注创建,满足类的单一职责原则
- 引入新的产品时,无需更改调用端,满足开闭原则
缺点
- 类的数目过多,可能造成系统的复杂度,可读性降低
是否使用抽象工厂模式,我们只需要关注,这些产品是否相互关联,在调用端是否交互。
谢谢 😮