调侃《Head First 设计模式》之工厂模式(二)

来源:互联网 发布:随州seo 编辑:程序博客网 时间:2024/05/01 17:45

         上一篇讲了简单工厂和工厂方法,在讲抽象工厂模式之前,现在先分析下简单工厂和工厂方法的主要特点和区别:简单工厂最大的优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件实时动态实例化相关的类,对于客户端来说去除了与具体产品的依赖,增加新的产品种类不用修改客户端。最大的缺点是如果要增加新的产品种类,就要修改工厂的代码,这违背了开放--关闭原则。工厂方法模式最大的特点是使得具体工厂创建方法的实现延迟到了子类。最大的优点是当增加新的产品种类时,只需要增加新的工厂类即可,无须修改原来的工厂,符合开放--关闭原则。缺点是增加新的产品种类要修改客户端代码。

     

     现在进入抽象工厂模式咯,继续以故事入手,还是从我们的比萨店说起。

     现在不同的比萨连锁店需要各自配备自己独特的一组原料,如下图:

     

              

      


     现在你要做的就是:

     1.为每个区域创建一个工厂,工厂可以生产一组该区域需要的原料。

     2.实现一组原料类供工厂使用。

     3.将新的工厂整合进原来的PizzaStore类。

     

    首先,按照原则,定义一个原料工厂接口:

    

      然后具体的区域的原料工厂:

      比如纽约原料工厂:(当然各种原料都有自己的接口,实现同接口的原料主要因地域而不同)

      

     

    

      基类Pizza中的prepare改为抽象,因为具体的Pizza的prepare过程获取的原料不同。

      比如奶酪比萨类:

     由于针对抽象编程,使用接口使得Pizza和原料解耦,Pizza关心的只是它拥有一个原料工厂就够了,至于原料的具体种类和生产方式它并不知道。具体生产出来的原料由原料工厂决定。

     回到Pizza店,比如纽约披萨店,只要传入具体的原料名称,就会生产出纽约风味的原料了。

    

      只要new出一个PizzaStore后,得到一个具体的Pizza,然后调用该Pizza的prepare方法,就可以得到所要的原料了。

    让我们看看官方对于抽象工厂模式的定义:

    抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

    关键词是对象家族同样客户端不需要知道具体产品是什么,所以实现了客户端从具体产品的解耦。

    以下是类关系图:

     所谓对象家族就是一个系列的产品,就比如纽约披萨原料,就是由FreshCalms,MarinaraSauce,ThinCrustDough,ReggianoCheese这一系列的原料组成,而NYPizzaIngredientFactory的工作就是创建这一系列的原料产品。

    观察敏锐的你是不是已经看出抽象工厂实际上运用着工厂方法呢?是的,没错。实际上抽象工厂的每个生产产品的方法也是工厂方法,而抽象工厂则是同时运用了多个工厂方法以生产一系列的产品。

   

   工厂方法和抽象工厂有太多的相似,对比下二者的特点:

   工厂方法的最大特点在于工厂接口只有一个工厂方法,具体产品的创建延迟到子类实现,客户端只需要知道获取了一个工厂对象,具体产品并不知道,实现客户端和具体产品的解耦。而抽象工厂可以看做是工厂方法的升级版本,因为工厂方法可以看做生产一个产品等级的,抽象工厂则是生产不同产品等级的相关联的系列产品。但是正因为此,抽象工厂的缺点在于当向系列产品添加新的产品要修改抽象工厂的方法,这违背开放--关闭原则的,而工厂方法若是添加新的产品只要扩展新的工厂类就可以了。

   

      祝大家工作愉快!

    

      

    

      

    

1 0
原创粉丝点击