关于工厂模式

        设计模式中,工厂模式在实际应用中出现的很频繁,此种模式包含简单工厂模式,工厂方法模式以及抽象工厂模式三种,这里做简单摘要整理.

        最近写一个小的应用程序,用到了简单工厂模式,其具体场景如下:

        多家银行,我们假设建设银行,中国银行两家,他们提供一些行业数据,通过这些业务数据,我们进行处理并展示到我们的业务前台.我们需要对建设银行和中国银行的业务数据进行不同方式处理.基于这个需求,如果我们设计两个类,分别代表中国银行和建设银行,代码如下:

public Class 中国银行
{
     pubic string GetSomething()
    {
          //中国银行相关代码
    }
}

public Class 建设银行
{
     pubic string GetSomething()
    {
          //建设银行相关代码
    }
}

如上两个类,我们在调用上面两个银行的方法时,如下:

public Class BankFactory
{
    public object GetBank(string _bank)
    {
       object obj;
       swich(_bank)
       {
          case "1":
             obj=new 中国银行();
             break;
          case "2":
             obj=new 建设银行();
             break;
          default:
             obj=new object();
             break;
       }
       return obj;
   } 
}

这个是一般思维,通过BankFactory类下的GetBank(string _bank)方法,我们可以获得具体需要的银行对象,我这用的是object返回类型,因为返回类型可能是中国银行也可能是建设银行或其他银行,故用object,这样就存在问题,在调用此方法后,不确定具体是那个对象,无法调用方法,如果在客户端再做判断强制转换,这样就复杂了.所以这里引入接口.

public interface IBank
{
      string GetSomething();
}

然后让中国银行和建设银行实现这个接口,那么我们上面的BankFactory类就可以如下改进:

public Class BankFactory
{
    public static IBank GetBank(string _bank)
    {
       IBank  ibank;
       swich(_bank)
       {
          case "1":
             ibank=new 中国银行();
             break;
          case "2":
             ibank=new 建设银行();
             break;
          default:
             break;
       }
       return ibank;
   } 
}

如上,就是一个简单工厂模式,她可以解决创建一系列有相关共性对象的问题.实现的方式是把实例的创建放到工厂类中,业务前台代码不关注具体创建工作.整个过程是部分符合开闭原则的,如果添加一个新的银行,业务前台代码无需变动,然后我们需要添加新的银行对象,比如农行;最后我们需要修改的地方只有BankFactory类,里面要加入有关农行的代码,因为工厂中包含业务逻辑判断,违反了高内聚责任分配原则.在这个地方,还有一些方式来实现,比如反射,自然这个_bank参数要与(命名空间+对象名称)相同.在工厂中用如下代码替换即可.

Ibank ibank = (IBank)Activator.CreateInstance(Type.GetType(_bank));

简单工厂模式在一些规模很小的系统中是可以拿来应用的,其简单清晰,基本可以比较好的解决对象创建的问题.

我们来看看工厂方法模式,保存简单工厂模式中的银行接口,具体银行类,我们来添加抽象工厂和具体工厂类.

    public abstract class AbFactory
    {
        public abstract IBank CreateBank();
    }
    //中国银行具体工厂
    public class Factory中国银行:AbFactory
    {
        public override IBank CreateBank()
        {
            IBank ba = new 中国银行();
            return ba;
        }
    }
   //建设银行具体工厂
   public class Factory建设银行:AbFactory
    {
        public override IBank CreateBank()
        {
            IBank ba = new 建设银行();
            return ba;
        }
    }

如上代码,我们创建一个抽象工厂类,然后继承抽象工厂创建中国银行,建设银行两个具体工厂,具体工厂负责创建具体的银行对象.所以这里工厂实际上和银行对应起来,有多少个银行,我就得添加多少个银行工厂.

下面我们对比一下简单工厂模式和工厂方法模式,很长一段时间我都认为工厂方法模式较繁琐,甚至觉得特别扭,可能是接触不到较大的项目的结果,呵呵.

简单工厂模式和工厂方法模式差在哪呢,从上面可以看到,简单工厂模式只有一个静态工厂,负责创建类;工厂方法模式有个抽象类,继而在抽象类下派生很多的具体工厂.从复杂度来讲,工厂方法模式要比简单工厂模式复杂.但从OCP上来讲,工厂方法模式确实让分工明晰下来,一个具体的工厂负责一个具体产品的创建,如果业务变化,需要添加银行,则再配套加上具体银行工厂即可,这里不涉及到任何其他修改,符合OCP,就较大的系统而言,有利于维护管理.

       最后说下抽象工厂模式,与工厂方法模式比起来,抽象工厂模式多了一个产品族的概念.产品族是啥意思呢,打个比方,扑克牌,有很多牌子,红心扑克,旅游纪念扑克等等,我们都晓得,一副扑克54张,不同牌子自然它的图案会不一样,这个我们可以把不同牌子的扑克叫做扑克产品族.个人爱好不一样,喜欢的扑克风格也不一样. 

      同样是扑克牌的例子,我们其实在玩牌的时候(单副玩法),一副扑克就已经满足我们了,同样,在抽象工厂模式的应用场景中,我们应对某个需求,也只是需要一个产品链即可完成功能,只是如果说客户想要另外一种风格了,我给他另外一个产品链,咋们再说到扑克,你觉得这幅牌丑,我们换幅美女扑克,其实我们就是玩牌.所以说,抽象工厂模式可以解决一些系统移植的难题,对于一个软件产品,它基本要符合某一类公司运作的需要,不能说这个公司可以用你的软件产品,而另外一个公司要用,而且公司的业务类型差不多,你的软件产品却卡到了,没法用,或者要费九牛二虎之力才能勉强用上,这样可能你的软件产品就存在缺陷.



 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值