工厂方法模式
定义一个可以产生对象的接口,但是让子类决定要产生哪一个类的对象。工厂方法模式让类的实例化程序延迟到子类中实施。
工厂方法模式的定义
工厂方法模式就是将类“产生对象的流程”集合管理的模式。集合管理带来的好处是:
- 能针对对象产生的流程定指规则
- 减少客户端参与对象生成的过程,尤其是对于那种对象生产过程过于复杂的,如果让客户端操作对象的组装过程,将使得客户端与该类的耦合度(即依赖度)过高,不利于后续的项目维护
参与者的说明如下:
- Product(产品类)
- 定义产品类的操作接口,而这个产品将由工厂产出
- ConcreteProduct(产品实现)
- 实现产品功能的类,可以不只定义一个产品实现类,这些产品实现类的对象都会由ConcreteCreator(工厂实现类)产生。
- Creator(工厂类)
- 定义能产生Product(产品类)的方法:FactoryMethod
- ConcreteCreator(工厂实现类)
- 实现FactoryMethod,并产生指定的ConcreteProduct(产品实现)。
具体实现
方法一:由子类实现
定义一个可以产生对象的接口,让子类决定要产生哪一个类的对象
public abstract class Product
{
}
//产品对象A
public class ConcreteProductA : Product
{
public ConcreteProductA()
{
Debug.Log("生成对象A");
}
}
//产品对象B
public class ConcreteProductB : Product
{
public ConcreteProductB()
{
Debug.Log("生成对象B");
}
}
public abstract class Creator
{
//子类返回对应的Product类型对象
public abstract Product FactoryMethod();
}
//生产ProductA的工厂
public class ConcreteCreatorProductA : Creator
{
public override Product FactoryMethod()
{
return new ConcreteProductA();
}
public ConcreteCreatorProductA()
{
Debug.Log("生产工厂:ConcreteCreatorProductA");
}
}
//生产ProductB的工厂
public class ConcreteCreatorProductB : Creator
{
public override Product FactoryMethod()
{
return new ConcreteProductB();
}
public ConcreteCreatorProductB()
{
Debug.Log("生产工厂:ConcreteCreatorProductB");
}
}
方法二:在FactoryMethod中增加参数
public abstract class Product
{
}
//产品对象A
public class ConcreteProductA : Product
{
public ConcreteProductA()
{
Debug.Log("生成对象A");
}
}
//产品对象B
public class ConcreteProductB : Product
{
public ConcreteProductB()
{
Debug.Log("生成对象B");
}
}
//重新实现factory mathod,以返回Product类型对象
public class ConcreteCreator_MethodType : Creator_MethodType
{
public ConcreteCreator_MethodType()
{
Debug.Log("生产工厂:ConcreteCreator_MethodType");
}
public override Product FactoryMethod(int Type)
{
switch (@Type)
{
case 1:
return new ConcreteProductA();
case 2:
return new ConcreteProductB();
default:
Debug.Log("Type[" + Type + "]无法产生对象");
break;
}
return null;
}
}
方法三:Creator泛型类
public abstract class Product
{
}
//产品对象A
public class ConcreteProductA : Product
{
public ConcreteProductA()
{
Debug.Log("生成对象A");
}
}
//产品对象B
public class ConcreteProductB : Product
{
public ConcreteProductB()
{
Debug.Log("生成对象B");
}
}
public class Creator_GenericClass<T> where T : Product, new()
{
public Creator_GenericClass()
{
Debug.Log("生产工厂Creator_GenericClass<" + typeof(T).ToString() + ">");
}
public Product FactoryMethod()
{
return new T();
}
}
public class Test
{
void UnitTest()
{
//使用Generic Class
//负责ProduceA的工厂
Creator_GenericClass<ConcreteProductA> Creator_ProductA = new Creator_GenericClass<ConcreteProductA>();
//负责ProduceB的工厂
Creator_GenericClass<ConcreteProductB> Creator_ProductB = new Creator_GenericClass<ConcreteProductB>();
}
}
方法四:FactoryMethod泛型方法
public abstract class Product
{
}
//产品对象A
public class ConcreteProductA : Product
{
public ConcreteProductA()
{
Debug.Log("生成对象A");
}
}
//产品对象B
public class ConcreteProductB : Product
{
public ConcreteProductB()
{
Debug.Log("生成对象B");
}
}
interface Creator_GenericMethod
{
Product FactoryMethod<T>() where T : Product, new();
}
public class ConcreteCreator_GenericMethod : Creator_GenericMethod
{
public ConcreteCreator_GenericMethod()
{
Debug.Log(("生产工厂:ConcreteCreator_GenericMethod"));
}
public Product FactoryMethod<T>() where T : Product, new()
{
return new T();
}
}
public class Test2
{
void UnitTest()
{
ConcreteCreator_GenericMethod theCreatorGM = new ConcreteCreator_GenericMethod();
Product theProductA = theCreatorGM.FactoryMethod<ConcreteProductA>();
Product theProductB = theCreatorGM.FactoryMethod<ConcreteProductB>();
}
}
使用工厂方法模式产生角色对象
参与者的说明如下:
- ICharacterFactory:负责产生角色类Icharacter的工厂接口,并提供两个工厂方法来产生不同阵营的角色对象:CharacterSoldier负责产生玩家阵营的角色对象;CharacterEnemy负责产生敌方阵营的角色对象。
- CharacterFactory:继承并实现ICharacter工厂接口的类,其中实现的工厂方法是实际产生对象的敌方。
- ISoldier、SoldierCapion:由工厂类产生的“产品”
- IEnemy、EnemyElf:由工厂类产生的另一项“产品”
工厂方法模式的优点
角色工厂类,将“角色类群组”产生的对象的实现,都整合到两个工厂方法(FactoryMethod)下,并将有关的程序从客户端删除,同时降低了客户端与“角色生产过程”的耦合度。此外,角色生产后的后续设置功能,也都在同意敌方是下面,让开发人员能快速了解类之间的关联性及设置的先后顺序。
与其他模式的合作
- 角色工厂中,产生不同阵营的角色时,会搭配建造者模式的需求,将需求的参数设置给各角色的建造者。
- 本地资源加载工厂若同时要求系统性能的优化,可使用代理者模式来优化加载性能。
- 属性产生工厂可使用享元模式来减少重复对象的产生。