设计模式 -- 简单工厂、工厂方法、抽象工厂模式

一、什么是工厂模式?

      工厂模式有一种非常形象的描述,建立对象的类就如一个工厂,而需要被建立的对象就是一个个产品;在工厂中加工产品,使用产品的人,不用在乎产品是如何生产出来的。从软件开发的角度来说,这样就有效的降低了模块之间的耦合。对于工厂模式,具体上可以分为三类:

1.简单工厂模式;

2.工厂方法模式;

3.抽象工厂模式;

      对于上面的三种工厂模式,从上到下逐步抽象,并且更具一般性,在GOF的介绍中,简单工厂和工厂方法合并在一起的。

二、简单工厂模式

1.什么是简单工厂模式?

     简单工厂模式属于类的创建型模式,又叫做静态工厂方法模式。通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

image


2.模式中包含的角色及其职责

      工厂(CFruitFactory)角色:简单工厂模式的核心,它负责实现创建所有实例的内部逻辑;

      抽象产品(CFruit)角色:所有产品的父类,它负责描述所有实例所共有的公共接口;

      具体产品(CBanana/CPear)角色:简单工厂模式所创建的具体实例对象;

3.适用场合

      在程序中,需要创建的对象很多,导致对象的new操作多且杂时,需要使用简单工厂模式;由于对象的创建过程是我们不需要去关心的,而我们注重的是对象的实际操作,所以,我们需要分离对象的创建和操作两部分,如此,方便后期的程序扩展和维护。

4.简单工厂模式的优缺点

      在这个模式中,工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的,有利于整个软件体系结构的优化。不难发现,简单工厂模式的缺点也正体现在其工厂类上,由于工厂类集中了所有实例的创建逻辑,所以“高内聚”方面做的并不好。另外,当系统中的具体产品类不断增多时,可能会出现要求工厂类也要做相应的修改,扩展性并不很好。那么能不能做到不修改具体工厂角色的情况下引进新的产品,比如新加一种类型的水果苹果(Apple)?

三、工厂方法模式

1.什么是工厂模式?

      工厂方法模式同样属于类的创建型模式又被称为多态工厂模式。工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。

image

2.类图角色和职责

      抽象工厂(CFruitFactory):工厂方法模式的核心,任何工厂类都必须实现这个接口;

      具体工厂(CBananaFactory/CPearServerFactory/CAppleFactory):具体工厂类是抽象工厂的一个实现,负责实例化产品对象;

      抽象产品(CFruit) :工厂方法模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口;

      具体产品(CBanana/…):工厂方法模式所创建的具体实例对象

3.适用场合

      工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。

      a.在设计的初期,就考虑到产品在后期会进行扩展的情况下,可以使用工厂方法模式;

      b.产品结构较复杂的情况下,可以使用工厂方法模式;


4.工厂方法模式和简单工厂模式比较

      A.结构上:工厂方法模式的核心是一个抽象工厂类,而简单工厂模式把核心放在一个具体类上。工厂方法模式可以允许很多具体工厂类从抽象工厂类中将创建行为继承下来,从而可以成为多个简单工厂模式的综合,进而推广了简单工厂模式。 

      B.产品类型:简单工厂模式产品单一,而工厂模式产品可以有多个

      C.扩展性:当系统扩展需要添加新的产品对象时,仅仅需要添加一个具体对象以及一个具体工厂对象,原有工厂对象不需要进行任何修改,也不需要修改客户端,很好的符合了“开放-封闭”原则(通过添加代码的方式,不是通过修改代码的方式完成功能的增强)。而简单工厂模式在添加新产品对象后不得不修改工厂方法,扩展性不好。

      简单工厂模式产品单一,工厂方法模式产品虽然可以有多个,但每次只能产生一个,那能不能同时产生多个呢?


四、抽象工厂模式

1.概念

     抽象工厂模式是所有形态的工厂模式中最为抽象和最其一般性的。抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品的具体类型的情况下,能够创建多个产品族的产品对象;

image

2.模式中包含的角色及其职责

     抽象工厂(CFruitFactory):抽象工厂模式的核心,包含对多个产品结构的声明,任何工厂类都必须实现这个接口;

      具体工厂(CSouthFruitFactory/…)角色:具体工厂类是抽象工厂的一个实现,负责实例化某个产品族中的产品对象;

      抽象(CFruit)角色:抽象模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。

      具体产品(CSouthBanana/CNorthBanana/…)角色:抽象模式所创建的具体实例对象

3.适用场合

      工厂方法模式适用于产品种类结构单一的场合,为一类产品提供创建的接口;而抽象工厂方法适用于产品种类结构多的场合,主要用于创建一组(有多个种类)相关的产品,为它们提供创建的接口;就是当具有多个抽象角色时,抽象工厂便可以派上用场。

4.其他问题

        如果要新加一种类型的水果苹果(Apple)?

image

1.增加CApple、CSouthApple、CNorthApple类

2.修改CFruitFactory、CSouthFruitFactory、CNorthFruitFactory类


5.用简单工厂来改进抽象工厂

image

1.增加CApple、CSouthApple、CNorthApple类

2.修改CFruitFactory类


6.利用反射技术进一步优化

      利用反射技术来去除简单工厂中switch或if,解除分支判断带来的耦合,这个可以直接看我们的项目代码。

7、工厂方法模式和抽象工厂模式比较

      1)、产品类型数量不同,工厂模式:要么生产香蕉、要么生产苹果、要么生产梨子;但是不能同时生产一个产品组;抽象工厂:能同时生产一个产品族(南方香蕉/苹果/梨子)。

      2)、工厂方法依靠继承解决问题,抽象工厂依靠对象的组合解决问题。工厂方法要解决的问题是:“把实例化过程延迟到子类”,实例化过程是在继承至抽象工厂类的派生类中完成的;而抽象工厂模式要解决的问题是:实例化并组织一系列相关的对象家族,这些对象通过组合的方式存在于抽象工厂类的派生类中,虽然实例化过程也是在派生类中完成,但是抽象工厂的侧重点不是关注如何实例化对象,而是关注如何组织一系列对象。

     3)、抽象工厂模式,就好比是两个工厂方法模式的叠加


主要参考:大话设计模式

猜你喜欢

转载自www.cnblogs.com/yzdai/p/9783090.html