【设计模式】创建型-①工厂模式
【设计模式】创建型-①工厂模式
注
学习核心
工厂模式核心
- 工厂模式的基本概念、应用场景
- 概念:为构建对象提供过渡接口(屏蔽对象创建的具体过程)
- 工厂模式的实现(静态工厂模式、抽象工厂模式、工厂方法模式)
- 工厂模式业务案例分析(老司机开车)
- 工厂模式的基本概念、应用场景
业务场景案例
- 【Spring 框架】:工厂方法模式创建对象
基本概念
工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来, 达到提高灵活性的目的
工厂模式在《Java 与模式》中分为三类:
简单工厂模式(Simple Factory)
工厂方法模式(Factory Method)
抽象工厂模式(Abstract Factory)
GOF 在《设计模式》一书中将工厂模式分为两类:
工厂方法模式(Factory Method)与 抽象工厂模式(Abstract Factory)。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类
【1】简单工厂模式
概念说明
简单工厂模式又称静态工厂方法模式。用于定义一个用于创建对象的接口
组成:
工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现
抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现
具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现
图示说明:

案例分析
场景说明:暴发户案例1
有一个暴发户,他家有三辆汽车——Benz 奔驰、Bmw 宝马、Audi 奥迪, 还雇了司机为他开车。不过,暴发户坐车时总是怪怪的:上 Benz 车后跟司机说“开奔驰车! ”, 坐上 Bmw 后他说“开宝马车!”,坐上 Audi 说“开奥迪车!”。此处以简单工厂模式来改造暴发户坐车的方式 ——现在暴发户只需要坐在车里对司机说句:“开车”就可以了
public class SimpleFactoryDemo {
/**
* 简单工厂方法测试
*/
public static void main(String[] args) {
// 开车测试
try {
// 告诉司机今天开什么车
Car car = Driver.driverCar("benz");
// 执行开车指令
car.drive();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 1.定义抽象产品角色
*/
interface Car {
// 定义开车方法
public void drive();
}
/**
* 2.确定具体的产品角色:奔驰、宝马、奥迪
*/
class Benz implements Car {
// 实现Car接口中的drive()方法
@Override
public void drive() {
System.out.println("Benz driving...");
}
}
class Bmw implements Car {
// 实现Car接口中的drive()方法
@Override
public void drive() {
System.out.println("Bmw driving...");
}
}
class Audi implements Car {
// 实现Car接口中的drive()方法
@Override
public void drive() {
System.out.println("Audi driving...");
}
}
/**
* 3.定义工厂类角色
*/
class Driver {
// 工厂方法.注意:返回类型为抽象产品角色
public static Car driverCar(String s) throws Exception {
// 判断逻辑,根据传入的参数返回具体的产品角色给 Client
if (s.equalsIgnoreCase("Benz")){
return new Benz();
}
else if (s.equalsIgnoreCase("Bmw")){
return new Bmw();
}
else if (s.equalsIgnoreCase("Audi")){
return new Audi();
}
else{
throw new Exception();
}
}
}
从开闭原则(对扩展开放;对修改封闭)上来分析下简单工厂模式。当暴发户增加了一辆车的时候,只要符合抽象产品制定的合同,那么只要通知工厂类知道就可以被客户使用了。所以对产品部分来说,它是符合开闭原则的;但是工厂部分好像不太理想,因为每增加一辆车,都要在工厂类中增加相应的业务逻辑或者判断逻辑,这显然是违背开闭原则的。可想而知对于新产品的加入,工厂类是很被动的。对于这样的工厂类(在我们的例子中 是为司机师傅),我们称它为全能类或者上帝类。此处举的例子是简单的情况,在实际应用中,很可能产品是一个多层次的树状结构
【2】工厂方法模式
概念说明
工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得它可以被子类继承。这 样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。
组成:
抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须 实现的接口或者必须继承的父类。在 java 中它由抽象类或者接口来实现。
具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
抽象产品角色:它是具体产品继承的父类或者是实现的接口。在 java 中一般有抽象类 或者接口来实现。
具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在 java 中由具体的类 来实现。
图示说明:

工厂方法模式使用继承自抽象工厂角色的多个子类来代替简单工厂模式中的“上帝类”。 正如上面所说,这样便分担了对象承受的压力;而且这样使得结构变得灵活起来——当有新的产品产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有的代码。可以看出工厂角色的结构也是符合开闭原则的!
案例分析
场景说明:暴发户案例2
在原有简单工厂方法构建的基础上将工厂角色拆分为抽象工厂角色和具体工厂角色
public class FactoryMethodDemo {
public static void main(String[] args) {
Driver driver = new BenzDrive();
Car car = driver.driveCar();
car.drive();
}
}
/**
* 1.定义抽象产品角色
*/
interface Car {
// 定义开车方法
public void drive();
}
/**
* 2.确定具体的产品角色:奔驰、宝马、奥迪
*/
class Benz implements Car {
// 实现Car接口中的drive()方法
@Override
public void drive() {
System.out.println("Benz driving...");
}
}
class Bmw implements Car {
// 实现Car接口中的drive()方法
@Override
public void drive() {
System.out.println("Bmw driving...");
}
}
class Audi implements Car {
// 实现Car接口中的drive()方法
@Override
public void drive() {
System.out.println("Audi driving...");
}
}
/**
* 3.定义抽象工厂角色
*/
interface Driver {
public Car driveCar();
}
/**
* 4.定义具体工厂角色
*/
class BenzDrive implements Driver {
@Override
public Car driveCar() {
return new Benz();
}
}
class BmwDriver implements Driver {
@Override
public Car driveCar() {
return new Bmw();
}
}
class AudiDriver implements Driver {
@Override
public Car driveCar() {
return new Audi();
}
}
可以看出工厂方法的加入,使得对象的数量成倍增长。当产品种类非常多时,会出现大量的与之对应的工厂对象,可以考虑使用简单工厂模式与工厂方法模式相结合的方式来减少工厂类:即对于产品树上类似的种类 (一般是树的叶子中互为兄弟的)使用简单工厂模式来实现。
下述情况中考虑使用工厂方法模式
- 当客户程序不需要知道要使用对象的创建过程
- 客户程序使用的对象存在变动的可能,或者根本就不知道使用哪一个具体的对象
扩展问题:简单工厂模式与工厂方法模式真正的避免了代码的改动了?
没有。在简单工厂模式中, 新产品的加入要修改工厂角色中的判断语句;而在工厂方法模式中,要么将判断逻辑留在抽象工厂角色中,要么在客户程序中将具体工厂角色写死(就象上面的例子一样)。而且产品对象创建条件的改变必然会引起工厂角色的修改。面对这种情况,Java 的反射机制与配置文件的巧妙结合突破了限制——这在 Spring 中完美的体现了出来
【3】抽象工厂模式
概念说明
产品族: 位于不同产品等级结构中,功能相关联的产品组成的家族

分析:图中的 BmwCar 和 BenzCar 就是两个产品树(产品层次结构);而如图所示的 BenzSportsCar 和 BmwSportsCar 就是一个产品族。他们都可以放到跑车家族中,因此功能 有所关联。同理 BmwBussinessCar 和 BenzSportsCar 也是一个产品族。
由此可知,抽象工厂模式和工厂方法模式的区别就在于需要创建对象的复杂程度上。而且抽象工厂模式是三个里面为抽象、最具一般性的。
抽象工厂模式的用意为:给客户端提供一个接口,可以创建多个产品族中的产品对象,而且使用抽象工厂模式还要满足以下条件
系统中有多个产品族,而系统一次只可能消费其中一族产品
同属于同一个产品族的产品以其使用
抽象工厂模式的各个角色(和工厂方法的如出一辙):
抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须 实现的接口或者必须继承的父类。在 java 中它由抽象类或者接口来实现。
具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体 产品的对象。在 java 中它由具体的类来实现。
抽象产品角色:它是具体产品继承的父类或者是实现的接口。在 java 中一般有抽象类或者接口来实现。
具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在 java 中由具体的类来实现。
类图如下:

基于产品模型理解工厂模式
工厂模式是用于创建对象的一种创建型设计模式,通过多种不同的设计和组合灵活创建对象,而工厂模式的演进则体现了这点,下述通过【工厂创建产品】的案例来理解三种不同的工厂模式的思路
工厂模式核心:
- 抽象产品角色:
interface Product(抽象产品接口) - 具体产品角色:
class XProduct implements Product{}(不同的产品实现子类) - 抽象工厂角色:
interface Factory(抽象工厂接口,定义生产方法规范) - 具体工厂角色:
class XFactory(具体工厂实现,根据工厂模式的不同实现不同的职责)
- 抽象产品角色:
工厂模式分类:
- ① 简单工厂模式:一个工厂可根据指定的类型创建不同的产品
- ② 工厂方法模式:有多个不同的工厂,每个工厂可以创建对应的产品(例如A工厂生产产品A,B工厂生产产品B,分门别类、职责划分明确)
- ③ 抽象工厂模式:有多个不同的工厂,每个工厂都可以创建所有的产品(例如A工厂可以生产A、B等产品,同理B工厂也可以生产所有类型的产品,每个工厂的职能更加丰富了)
工厂模式理解
简单工厂:相当于只有一种工厂生产不同的产品
- 抽象产品角色:Product(接口)
- 具体产品角色:AProduct、BProduct
- 工厂类:ProductFactory(具体类)
工厂方法:在简单工厂的模式下进化,相当于有多类工厂,每类工厂生产指定类的产品
- 抽象产品角色:Product(接口)
- 具体产品角色:AProduct、BProduct
- 抽象工厂角色:ProductFactory(接口)(create)
- 具体工厂角色:AProductFactory、BProductFactory
抽象工厂:每类工厂都可以生产不同类产品,和工厂方法模式类似,也是拆分为4个角色,但其主要的区别在于对工厂角色的设计,它对工厂内的生产方法做了进一步的拆分(例如原工厂方法模式中工厂的生产接口定义了一个create方法,而抽象工厂模式设计中会对这个create进行细分,拆分为createA、createB等方法,相当于每类工厂都可以生产指定的产品)
抽象产品角色:Product(接口)
具体产品角色:AProduct、BProduct
抽象工厂角色:ProductFactory(接口)(createA、createB)
具体工厂角色:AProductFactory、BProductFactory
【1】简单工厂模式
/**
* 简单工厂模式:一个工厂可以根据不同产品类型生产多种产品
*/
public class SimpleFactory {
// ① 抽象产品角色
static interface Product {
void fun(); // 产品功能
}
// ② 具体产品角色
static class AProduct implements Product {
@Override
public void fun() {
System.out.println("product a");
}
}
static class BProduct implements Product {
@Override
public void fun() {
System.out.println("product b");
}
}
// ③ 简单工厂(一个工厂创建所有类型的产品)
static class ProductFactory {
public Product getProduct(String type) {
Product p = null;
switch (type) {
case "A":
p = new AProduct();
break;
case "B":
p = new BProduct();
break;
default:
p = null; // ... other product
break;
}
return p;
}
}
public static void main(String[] args) {
ProductFactory factory = new ProductFactory();
Product pa = factory.getProduct("A");
pa.fun();
Product pb = factory.getProduct("B");
pb.fun();
}
}
【2】工厂方法模式
/**
* 工厂方法模式:多类工厂创建产品,每类工厂创建对应类型的产品
*/
public class FactoryMethod {
// ① 抽象产品角色
static interface Product {
void fun(); // 产品功能
}
// ② 具体产品角色
static class AProduct implements Product {
@Override
public void fun() {
System.out.println("product a");
}
}
static class BProduct implements Product {
@Override
public void fun() {
System.out.println("product b");
}
}
// ③ 抽象工厂角色
static interface Factory {
Product createProduct();
}
// ④ 具体工厂角色
// A 工厂创建A产品
static class AFactory implements Factory {
@Override
public Product createProduct() {
return new AProduct();
}
}
// B 工厂创建B产品
static class BFactory implements Factory {
@Override
public Product createProduct() {
return new BProduct();
}
}
// 工厂方法(多类工厂创建所有对应类型的产品)
public static void main(String[] args) {
AFactory aFactory = new AFactory();
Product pa = aFactory.createProduct();
pa.fun();
BFactory bFactory = new BFactory();
Product pb = bFactory.createProduct();
pb.fun();
}
}
【3】抽象工厂模式
/**
* 抽象工厂(创建多类工厂,支持每类工厂灵活创建不同的产品)
*/
public class AbstractFactory {
// ① 抽象产品角色
static interface Product {
void fun(); // 产品功能
}
// ② 具体产品角色
static class AProduct implements Product {
@Override
public void fun() {
System.out.println("product a");
}
}
static class BProduct implements Product {
@Override
public void fun() {
System.out.println("product b");
}
}
// ③ 抽象工厂角色
static interface Factory {
Product createProductA();
Product createProductB();
Product createOtherProduct();
}
// ④ 具体工厂角色
// A 工厂
static class AFactory implements Factory {
@Override
public Product createProductA() {
System.out.println("AFactory create A-Product");
return new AProduct();
}
@Override
public Product createProductB() {
System.out.println("AFactory create B-Product");
return new BProduct();
}
@Override
public Product createOtherProduct() {
return null;
}
}
// B 工厂
static class BFactory implements Factory {
@Override
public Product createProductA() {
System.out.println("BFactory create A-Product");
return new AProduct();
}
@Override
public Product createProductB() {
System.out.println("BFactory create A-Product");
return new BProduct();
}
@Override
public Product createOtherProduct() {
return null;
}
}
public static void main(String[] args) {
// 创建A工厂
AFactory aFactory = new AFactory();
Product pa1 = aFactory.createProductA();
pa1.fun();
Product pb1 = aFactory.createProductB();
pb1.fun();
// 创建B工厂
BFactory bFactory = new BFactory();
Product pa2 = bFactory.createProductA();
pa2.fun();
Product pb2 = bFactory.createProductB();
pb2.fun();
}
}
