问题:
为了满足一种业务需要需要多个算法,(如:审批业务,有部门经理审批,总监审批,总裁审批...)。因为是同一类业务处理,所以我们经常会抽象出这些算法的公共属性和方法以形成抽象基类或者接口,这样我们可以通过声明一个指向基类(或接口)的指针来指向实际的子类实现,达到了多态的目的。因为要为每一种算法在使用之前都要先创建一个实例,然后才能使用。这里就出现的一个问题n多的子类继承自抽象基类,我们不得不在每次要用到子类的地方就编写诸如new ×××;的代码 。这个实例化工作有谁来做呢,如果交给客户端去做,客户端势必要进行相应的逻辑判断,来决定调用那一算法去实例化相应的子类对象,这样就暴露了实现,不符合 高内聚(Cohesion)和低耦合(Coupling)面向对象的设计要求。因此建立一个工厂类,让工厂来负责具体的算法的创建(逻辑判断),客户端就不必知道具体的算法了,而且,这样做就可以统一接口。
定义:
简单工厂模式是类的创建模式,又叫静态工厂方法模式,由一个工厂类根据传入的参量决定创建出哪一种产品类的实例,涉及到工厂角色、抽象产品角色以及具体产品角色。
GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。
意图:
提供一个类,由它负责根据一定的条件创建某一具体类的实例,客户端不参与创建具体产品,仅通过传入参数选择需要“消费”对象。而不必管这些对象究竟如何创建及如何组织的,从而使得客户端和实现之间的解耦
参与者:
•工厂角色(Creator)
是简单工厂模式的核心,它负责实现创建所有具体产品类的实例。工厂类可以被外界直接调用,创建所需的产品对象。
•抽象产品角色(Product)
是所有具体产品角色的父类,它负责描述所有实例所共有的公共接口。
•具体产品角色(Concrete Product)
继承自抽象产品角色,一般为多个,是简单工厂模式的创建目标。工厂类返回的都是该角色的某一具体产品。
UML图:
实例说明:
1)审批实例
业务需要一个审批流程需要 有部门经理审批,总监审批。用户登录后根据不同的身份角色实例化相应的对象完成,uml图如下:
代码:
/// 审核接口
/// </summary>
public interface ICheckup
{
public void DoCheck();
}
/// <summary>
/// 经理审核具体类
/// </summary>
public class ManagerCheckup : ICheckup
{
public void DoCheck()
{
//...
}
}
/// <summary>
/// 总监审核具体类
/// </summary>
public class DirectorCheckup : ICheckup
{
public void DoCheck()
{
//...
}
}
/// <summary>
/// 审核工厂类
/// </summary>
public class CheckupFactory : ICheckup
{
public ICheckup CreateCheck(int roleId)
{
if (roleId == 1)
{
return new ManagerCheckup();
}
else if (roleId == 2)
{
return new DirectorCheckup();
}
return null;
}
}
/// <summary>
/// 客户端类
/// </summary>
class Program
{
void Checkup()
{
CheckupFactory factory = new CheckupFactory();
ICheckup checkup = factory.CreateCheck(2);
checkup.DoCheck();
}
}
2)诺基亚手机工厂
比如Nokia简单工厂就是只有NokiaFactory工厂类,工厂方法就是CreateNokiaPhone,参数是Nokia手机型号,根据不同型号创建不同的Nokia手机。,uml图如下:
代码:
/// 手机接口
/// </summary>
public interface INokiaPhone
{
public string GetPhoneName();
}
/// <summary>
/// N8手机具体类
/// </summary>
public class N8Phone : INokiaPhone
{
public string GetPhoneName()
{
return "我是N8";
}
}
/// <summary>
/// N9手机具体类
/// </summary>
public class N9Phone : INokiaPhone
{
public string GetPhoneName()
{
return "我是N9";
}
}
/// <summary>
/// 手机生产工厂类
/// </summary>
public class PhoneFactory
{
public INokiaPhone CreateNokiaPhone(string phoneName)
{
switch (phoneName)
{
case "N8":
return new N8Phone();
case "N9":
return new N9Phone();
default:
return null;
}
}
}
/// <summary>
/// 客户端类
/// </summary>
class Program
{
void CreatePhone()
{
PhoneFactory factory = new PhoneFactory();
INokiaPhone phone = factory.CreateNokiaPhone("N8");
phone.GetPhoneName();
}
}
优点:
•简单工厂模式能够根据客户端给定的信息,决定究竟应该创建哪个具体类的对象。客户端不参与创建具体产品对象的工作。
•外界与具体类隔离开来,偶合性低。
•明确区分了各自的职责和权力,有利于整个软件体系结构的优化。
缺点:
•工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则
•它所能创建的类只能是事先教考虑到的,如果需要添加新的类,则就需要改变工厂类了。违反开闭原则
应用情景:
•工厂类负责创建的对象是已知的情况,否者就会违反开闭原则 。
•客户只知道传入了工厂类的参数,对如何创建对象(逻辑)不关心 。