设计模式摘要(核心篇)四、工厂模式

白墨曰:创建对象,是极可能变化的过程,把这个过程封装到工厂中。

工厂模式包含:

  1. 简单工厂
  2. 工厂方法
  3. 抽象工厂

(一)简单工厂

简单工厂不是一个设计模式,更像一种编程习惯。

模式应用

场景

一家比萨店,生产各种比萨

应用类图:

参考代码:简单工厂

(二)工厂方法模式

定义:工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

作用

工厂方法用来处理对象的创建,并将这样的行为封装在子类中。这样,客户程序中关于超类的代码就和子类对象创建代码解耦了。

注意点

  • 将一个 orderPizza() 方法和一个工厂方法联合起来,就可以成为一个框架。除此之外,工厂方法将生产知识封装斤各个创建者,这样的做法,也可以被视为是一个框架。
  • “工厂”的好处:1. 将创建对象的代码集中在一个对象或方法中,可以避免代码中的重复,更方便以后的维护;2.客户在实例化对象时,只会依赖于接口,而不是具体类,这让代码更有弹性,可以应对未来的扩展。
  • 将创建对象的代码用栅栏围起来。

工厂方法 VS 简单工厂

工厂方法与简单工厂很类似,但用法不同。简单工厂把全部的事情,在一个地方处理完了,然而工厂方法却是创建一个框架,让子类决定要如何实现。简单工厂不具备工厂方法的弹性,因为简单工厂不能变更正在创建的产品。这里的具体商店是扩展自一个类,此类有一个抽象的方法 createPizza()。由每个商店自行负责 createPizza() 方法的行为。在简单工厂中,工厂是另一个由 PizzaStore 使用的对象。

设计原则

  • “依赖倒置原则”:要依赖抽象,不要依赖具体类。(不能让高层组件依赖低层组件,而且,不管高层或低层组件,“两者”都应该依赖于抽象)

指导方针

  • 变量不可以持有具体类的引用。(如果使用 new,就会持有具体类的引用。你可以改用工厂来避开这样的做法。)
  • 不要让类派生自具体类。(如果派生自具体类,你就会依赖具体类。请派生自一个抽象(接口或抽象类))
  • 不要覆盖基类中已实现的方法。(如果覆盖基类已实现的方法,那么你的基类就不是一个真正适合被继承的抽象。基类中已实现的方法,应该由所有的子类共享。)

模式应用

场景

出现各种比萨加盟店,遵循相同的流程,但允许不同的口味。

核心代码(给比萨店使用的框架)

可让比萨制作活动局限于 PizzaStore 类,而同时又能让这些加盟店依然可以自由地制作该区域的风味。

应用类图

参考代码:工厂方法

(三)抽象工厂模式

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

模式类图

作用

抽象工厂允许客户使用抽象的接口来创建一组相关的产品,而不需要知道(或关心)实际产出的具体产品是什么。这样一来,客户就从具体的产品中被解耦。

注意点

  • 抽象工厂的方法经常以工厂方法的方式实现。

工厂方法VS抽象工厂

工厂方法:继承;创建一个产品

抽象工厂:组合;创建产品家族;如果加入新产品必须改变接口

模式应用

场景

建立比萨原料工厂。

应用类图

参考代码:抽象工厂