1, 简单工厂
简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫静态工厂方法模式(Static FactoryMethod Pattern),是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类
简单工厂模式的核心思想就是:有一个专门的类来负责创建实例的过程
不足:
由于工厂本身包括了所有的收费方式,商场是可能经常性的更改打折额度和返利额度,每次维护或扩展收费方法都要改动这个工厂,以致代码需重新编译部署,很麻烦
代码如下:
//现金收费工厂类
class CashFactory
{
public static CashSupercreateCashAccept(string type)
{
CashSuper cs = null;
switch (type)
{
case "正常收费":
cs = new CashNormal();
break;
case "满300返100":
CashReturn cr1 = newCashReturn("300", "100");
cs = cr1;
break;
case "打八折":
CashRebate cr2 = newCashRebate("0.8");
cs = cr2;
break;
}
return cs;
}
2, 工厂方法
工厂方法模式是定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
代码如下:
//雷锋工厂
interfaceIFactory
{
leifeng createleifeng();
}
//学雷锋的大学生工厂
classUndergraduateFactory : IFactory
{
public leifeng createleifeng()
{
return new Undergraduate();
}
}
//社区志愿者工厂
classVolunteerFactory : IFactory
{
public leifeng createleifeng()
{
return new Volunteer();
}
}
工厂方法模式:针对每一个对象创建一个工厂
优点:
工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行。如果需要加功能,本来是该工厂类的,而现在是修改客户端。
缺点:
由于每加一个产品,就需要加一个产品工厂的类,增加了额外的开发量。
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
代码如下:
//IFactory接口
interface IFactory
{
Iuser createUser();
}
//SQLServerFactory类,实现IFactory接口,实例化SQLServerUser
class SQLServerFactory : IFactory
{
public Iuser createUser()
{
return new SQLServerUser();
}
}
//AccessFactory类,实现IFactory接口,实例化AccessUser
class AccessFactory : IFactory
{
public Iuser createUser()
{
return new AccessUser();
}
}
抽象工厂方法:IFactory是一个抽象工厂接口,它里面应该包括所有的产品创建的抽象方法。
优点:
1,易于交换产品系列
2,它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户端代码中。
缺点:
当我们要增加项目表则我需要至少添加3个类,还需要改动IFactory,SqlserverFactory,和AccessFactory才可以完全实现。
改进:
用简单工厂来改进抽象工厂
去除IFactory,SqlserverFactory,和AccessFactory三个工厂类,取而代之的是DataAccess类。
代码如下:
class DataAccess
{
private static readonly string db = "Sqlserver";
//private static readonly string db="Access";
public static Iuser createuser()
{
Iuser result = null;
switch (db)
{
case "Sqlserver":
result = new SQLServerUser();
break;
case "Access":
result = new AccessUser();
break;
}
return result;
}
不足:
如果我现在要增加Oracle数据库访问,本来抽象工厂只增加OracleFactory工厂类就可以了,但现在就比较麻烦了。
改进2:用反射+抽象工厂的数据访问程序
改进3:用反射+配置文件实现数据访问程序
三种工厂模式对比:
- 简单工厂:简单工厂模式的工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。不修改代码的话,是无法扩展的。
- 工厂方法:工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。在同一等级结构中,支持增加任意产品。
- 抽象工厂:抽象工厂是应对产品族概念的。比如说,每个汽车公司可能要同时生产轿车,货车,客车,那么每一个工厂都要有创建轿车,货车和客车的方法。应对产品族概念而生,增加新的产品线很容易,但是无法增加新的产品。
举例说明:
简单工厂的由来:以前都是我自己生产自己的汽车(自产自用),这样的话我和汽车之间就是强耦合,没有我就没办法生产。
简单工厂:一个汽车公司将各种各样的汽车生产都放在了一个工厂里实现(工厂只负责生产,我只负责使用,降低了我和汽车之间的耦合)
工厂方法:汽车公司将不同种的汽车在不同的工厂内实现.例如:轿车在生产轿车的工厂生产,汽车在生产汽车的工厂生产等(增加新的产品)。
抽象工厂:一个汽车公司同时生产汽车,轿车,客车,那么这个汽车公司的每个工厂都要实现生产汽车,轿车,客车的方法。当我要生产各种汽车的不同品牌时,则需要使用抽象工厂模式。也就是产品族的概念。(增加产业线)
区别:
- 简单工厂 : 用来生产同一等级结构中的任意产品。(对于增加新的产品,无能为力)
- 工厂模式 :用来生产同一等级结构中的固定产品。(支持增加任意产品)
- 抽象工厂:用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)
以上三种工厂方法在等级结构和产品族这两个方向上的支持程度不同。所以要根据情况考虑应该使用哪种方法。