工厂模式

声明一 本文内容属于《Head First 设计模式》阅读笔记,文中涉及到的知识案例等直接或间接来源于该书。《Head First 设计模式》通过有趣的图表+文字的形式,让人自然学习设计模式,非常棒推荐阅读
声明二 工厂模式使用灵活,在不同的情境下,可能有不同的表现形式。本文的重点在介绍工厂模式,而非使用工厂模式,所以在示例代码中的一些地方作了简化处理,更方便理解。在实际开发应用时,还可对示例中的代码进一步优化(如:在类型上使用枚举,而不使用字符串等)。
声明三 本文代码部分全部以图片的形式给出,如有需要,可直接去文末Github链接处下载测试项目。


概述

        工厂模式的设计出发点是对扩展开放,对修改关闭;常见的工厂模式可分为简单工厂、静态工厂、工厂方法、抽象工厂;其中简单工厂与静态工厂可以说是一种基本的编程习惯,而工厂方法以及抽象工厂才是工厂模式的重心。。


简单工厂 提供一个工厂类,通过工厂类相应的实例方法传入不同的参数,来创建不同的对象

示例

  • 情景介绍:
            现有一家披萨店,这家披萨店制作披萨需要两步:第一步,获取到不同类型的生披萨;第二步,将生披萨进行准备(如加佐料等)、烘烤、切片、裝盒后,得到最终可食用的熟披萨。
  • (生的)披萨类:
    工厂模式_第1张图片
  • (生的)披萨的实现有:
    工厂模式_第2张图片
  • 不使用工厂模式(的写法):
    工厂模式_第3张图片
  • 使用工厂模式(的写法):
    • 编写工厂类:
      工厂模式_第4张图片
    • 使用工厂类:
      工厂模式_第5张图片

静态工厂 提供一个工厂类,通过工厂类相应的静态方法传入不同的参数,来创建不同的对象(即:静态工厂与简单工厂几乎一样,只不过简单工厂用的是实例方法,而静态工厂用的是静态方法)。

示例

  • 情景介绍:
            现有一家披萨店,这家披萨店制作披萨需要两步:第一步,获取到不同类型的生披萨;第二步,将生披萨进行准备(如加佐料等)、烘烤、切片、裝盒后,得到最终可食用的熟披萨。
  • (生的)披萨类:
    工厂模式_第6张图片
  • (生的)披萨的实现有:
    工厂模式_第7张图片
  • 不使用工厂模式(的写法):
    工厂模式_第8张图片
  • 使用工厂模式(的写法):
    • 编写工厂类:
      工厂模式_第9张图片
    • 使用工厂类:
      工厂模式_第10张图片

工厂方法在抽象类中,定义一个抽象方法来获取需要的对象,在常规方法里使用这个对象编写逻辑。不同的子类对该抽象方法进行不同的实现,来达到工厂的效果(,如果有必要,子类还可以重写这个抽象类的其它方法)。

示例

  • 情景介绍:
            现有全球连锁披萨店,披萨店制作披萨需要两步:第一步,获取到不同类型的生披萨;第二步,将生披萨进行准备(如加佐料等)、烘烤、切片、裝盒后,得到最终可食用的熟披萨。且每个国家对同一种披萨可能有属于自己国家的口味,如:Abc国的芝士披萨是这种味,Xyz国的芝士披萨是另一种味。
  • (生的)披萨类:
    工厂模式_第11张图片
  • (生的)披萨的实现有:
    工厂模式_第12张图片
  • 对于Abc国以及Xyz国来说,可能有自己的生披萨实现:
    工厂模式_第13张图片
  • 不使用工厂模式(的写法):
    工厂模式_第14张图片
  • 使用工厂模式(的写法):
    • 编写抽象父类,定义工厂方法:
      工厂模式_第15张图片
    • 编写子类,实现工厂方法:
      • Abc国的子类实现:
        工厂模式_第16张图片
      • Xyz国的子类实现:
        工厂模式_第17张图片
  • 使用测试:
    • 编写测试类:
      工厂模式_第18张图片
    • 运行main方法,控制台输出:
      工厂模式_第19张图片

抽象工厂提供一个接口,用于获得一系列相关的对象(即:用于获得一组对象)。至于获得到的这组对象是什么样子的,由抽象工厂的实现类决定。

示例

  • 情景介绍:
            一个煎饼果子,需要的原料有面团、蔬菜、油条、腐乳、葱花。现有一家连锁的煎饼果子店,在Abc省以及Xyz省都有分店。但是Abc省与Xyz省,用的原料却有差异。

  • 从抽象工厂出发:
            从【一个煎饼果子,需要的原料有面团、蔬菜、油条、腐乳、葱花】可知:面团、蔬菜、油条、腐乳、葱花都是煎饼果子原料,根据抽象工厂的概念,我们可以提供一个接口,用于获得面团、蔬菜、油条、腐乳、葱花。

  • 设计:
    工厂模式_第20张图片

  • 抽象工厂与实现类:
    工厂模式_第21张图片

  • 煎饼果子基类与子类:
    工厂模式_第22张图片

  • 上述示例的关键代码:

    • 抽象工厂PancakeIngredientFactory:
      工厂模式_第23张图片

    • 抽象工厂实现类PancakeIngredientFactory:
      工厂模式_第24张图片
      注:XyzPancakeIngredientFactory类与AbcPancakeIngredientFactory类类似,这里就不给出了。

    • 煎饼果子基类BasePancake:
      工厂模式_第25张图片

    • 具有地方特色的煎饼果子类AbcPancake:
      工厂模式_第26张图片
      注:XyzPancake类与AbcPancake类类似,这里就不给出了。

  • 测试一下:
    工厂模式_第27张图片

    • 控制台输出:
      工厂模式_第28张图片

工厂模式学习完毕!



^_^ 如有不当之处,欢迎指正

^_^ 参考资料
        《Head First 设计模式》
Eric Freeman & Elisabeth Freeman with Kathy Sierra & Bert Bates著,O’Reilly Taiwan公司译,UMLChina改编

^_^ 测试代码托管链接
         https://github.com/JustryDeng…DesignPattern

^_^ 本文已经被收录进《程序员成长笔记(六)》,笔者JustryDeng

你可能感兴趣的:(Head,First设计模式,工厂模式,工厂方法,抽象工厂,设计模式,java)