工厂设计模式很常用,分为简单工厂,工厂方法和抽象工厂。

核心本质

  • 实例化对象不使用new,用工厂方法代替
  • 将选择实现类,创建对象统一管理和控制。从而将调用者跟我们实现类解耦

OOP七大原则

  1. 开闭原则:一个软件的实体应当对扩展开放,对修改关闭
  2. 依赖倒转原则:要针对接口编程,不要针对实现编程
  3. 迪米特法则:只与你直接的朋友通信,而避免与陌生人通信

应用场景

  • JDK中Calendar的getInstance方法
  • JDBC中的Connection对象的获取
  • Spring中IOC容器创建管理bean对象
  • 反射中Class对象的newInstance方法

三种模式

简单工厂(Simple Factory)

用来生产同一等级结构中的任意产品(对于增加新的产品,需要扩展已有代码)

如下图需要扩展一类新车–Ford,需要扩展车工厂里面的代码
20201120190743

Car接口

1
2
3
4
5
6
7
8
9
10
11
12
package com.marlowe.factory.simple;

/**
* @program: GoF23
* @description: 车接口
* @author: Marlowe
* @create: 2020-11-20 17:00
**/
public interface Car {
public void name();
}

以下两个实体类实现Car接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.marlowe.factory.simple;

/**
* @program: GoF23
* @description: 宝马
* @author: Marlowe
* @create: 2020-11-20 17:01
**/
public class Bmw implements Car {
@Override
public void name() {
System.out.println("我是宝马!");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.marlowe.factory.simple;

/**
* @program: GoF23
* @description: 特斯拉
* @author: Marlowe
* @create: 2020-11-20 17:01
**/
public class Tesla implements Car{
@Override
public void name() {
System.out.println("我是特斯拉!");
}
}

CarFactory工厂类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.marlowe.factory.simple;

/**
* @program: GoF23
* @description: 汽车工厂
* 静态工厂模式
* 开闭原则
* @author: Marlowe
* @create: 2020-11-20 17:02
**/
public class CarFactory {
/**
* 方法一
*
* @param car
* @return
*/
public static Car getCar(String car) {
if ("宝马".equals(car)) {
return new Bmw();
} else if ("特斯拉".equals(car)) {
return new Tesla();
} else {
return null;
}
}

/**
* 方法二
*
* @return
*/
public static Car getBmw() {
return new Bmw();
}

public static Car getTesla() {
return new Tesla();
}
}

主类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.marlowe.factory.simple;

/**
* @program: GoF23
* @description: 顾客
* @author: Marlowe
* @create: 2020-11-20 17:03
**/
public class Comsumer {
public static void main(String[] args) {
System.out.println("通过方式1获取:");
Car car1 = CarFactory.getCar("宝马");
Car car2 = CarFactory.getCar("特斯拉");
car1.name();
car2.name();
System.out.println("通过方式2获取:");
Car bmw = CarFactory.getBmw();
Car tesla = CarFactory.getTesla();
bmw.name();
tesla.name();
}
}

1
2
3
4
5
6
7
结果:
通过方式1获取:
我是宝马!
我是特斯拉!
通过方式2获取:
我是宝马!
我是特斯拉!

工厂方法(Factory Method)

用来生产同一等级结构中的固定产品(支持增加任意产品)

如下图需要扩展一类新车–Ford,横向扩展即可
20201120214332

Car接口

1
2
3
4
5
6
7
8
9
10
11
12
package com.marlowe.factory.method;

/**
* @program: GoF23
* @description: 车接口
* @author: Marlowe
* @create: 2020-11-20 17:00
**/
public interface Car {
public void name();
}

以下两个实体类实现Car接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.marlowe.factory.method;

/**
* @program: GoF23
* @description: 宝马
* @author: Marlowe
* @create: 2020-11-20 17:01
**/
public class Bmw implements Car {
@Override
public void name() {
System.out.println("我是宝马!");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.marlowe.factory.method;

/**
* @program: GoF23
* @description: 特斯拉
* @author: Marlowe
* @create: 2020-11-20 17:01
**/
public class Tesla implements Car {
@Override
public void name() {
System.out.println("我是特斯拉!");
}
}

CarFactory接口

1
2
3
4
5
6
7
8
9
10
11
12
package com.marlowe.factory.method;

/**
* @program: GoF23
* @description: 工厂方法模式
* @author: Marlowe
* @create: 2020-11-20 18:54
**/
public interface CarFactory {
Car getCar();
}

以下两个类实现CarFactory接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.marlowe.factory.method;

/**
* @program: GoF23
* @description:
* @author: Marlowe
* @create: 2020-11-20 18:55
**/
public class BmwFactory implements CarFactory {
@Override
public Car getCar() {
return new Bmw();
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.marlowe.factory.method;

/**
* @program: GoF23
* @description:
* @author: Marlowe
* @create: 2020-11-20 18:55
**/
public class TeslaFactory implements CarFactory {
@Override
public Car getCar() {
return new Tesla();
}
}

主类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.marlowe.factory.method;

import com.marlowe.factory.simple.CarFactory;

/**
* @program: GoF23
* @description: 顾客
* @author: Marlowe
* @create: 2020-11-20 17:03
**/
public class Comsumer {
public static void main(String[] args) {
Car car1 = new TeslaFactory().getCar();
Car car2 = new BmwFactory().getCar();
Car car3 = new FordFactory().getCar();
car1.name();
car2.name();
car3.name();
}
}

1
2
3
4
结果:
我是特斯拉!
我是宝马!
我是福特!

抽象工厂(Abstract Factory)

围绕一个超级工厂创建其他工厂,该工厂又称为其他工厂的工厂

抽象工厂模式提供了一个创建一系列相关或者相互依赖对象的接口,无需指定它们具体的类

抽象产品工厂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.marlowe.factory.abstract1;

/**
* @program: GoF23
* @description: 抽象产品工厂
* @author: Marlowe
* @create: 2020-11-21 10:54
**/
public interface IProductFactory {
/**
* 生产手机
*
* @return
*/
IPhoneProduct iPhoneProduct();

/**
* 生产路由器
*
* @return
*/
IRouterProduct iRouterProduct();
}

小米工厂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.marlowe.factory.abstract1;

/**
* @program: GoF23
* @description: 小米工厂
* @author: Marlowe
* @create: 2020-11-21 10:57
**/
public class XiaomiFactory implements IProductFactory {
@Override
public IPhoneProduct iPhoneProduct() {
return new XiaomiPhone();
}

@Override
public IRouterProduct iRouterProduct() {
return new XiaomiRouter();
}
}

华为工厂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.marlowe.factory.abstract1;

/**
* @program: GoF23
* @description: 华为工厂
* @author: Marlowe
* @create: 2020-11-21 10:57
**/
public class HuaweiFactory implements IProductFactory {
@Override
public IPhoneProduct iPhoneProduct() {
return new HuaweiPhone();
}

@Override
public IRouterProduct iRouterProduct() {
return new HuaweiRouter();
}
}

手机产品接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.marlowe.factory.abstract1;

/**
* @program: GoF23
* @description: 手机产品接口
* @author: Marlowe
* @create: 2020-11-20 22:38
**/
public interface IPhoneProduct {
/**
* 开机
*/
void start();

/**
* 关机
*/
void shutdown();

/**
* 打电话
*/
void call();

/**
* 发信息
*/
void sendMessage();
}

以下小米手机和华为手机分别实现手机产品接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.marlowe.factory.abstract1;

/**
* @program: GoF23
* @description: 小米手机
* @author: Marlowe
* @create: 2020-11-20 22:41
**/
public class XiaomiPhone implements IPhoneProduct {
@Override
public void start() {
System.out.println("打开小米手机");
}

@Override
public void shutdown() {
System.out.println("关闭小米手机");
}

@Override
public void call() {
System.out.println("小米手机打电话");

}

@Override
public void sendMessage() {
System.out.println("小米手机发信息");

}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.marlowe.factory.abstract1;

/**
* @program: GoF23
* @description: 华为手机
* @author: Marlowe
* @create: 2020-11-20 22:44
**/
public class HuaweiPhone implements IPhoneProduct {
@Override
public void start() {
System.out.println("打开华为手机");
}

@Override
public void shutdown() {
System.out.println("关闭华为手机");
}

@Override
public void call() {
System.out.println("华为手机打电话");
}

@Override
public void sendMessage() {
System.out.println("华为手机发信息");
}
}

路由器产品接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.marlowe.factory.abstract1;

/**
* @program: GoF23
* @description: 路由器产品接口
* @author: Marlowe
* @create: 2020-11-20 22:40
**/
public interface IRouterProduct {
/**
* 开机
*/
void start();

/**
* 关机
*/
void shutdown();

/**
* 打开wifi
*/
void openWifi();

/**
* 设置
*/
void setting();
}

以下小米路由器和华为路由器分别实现路由器产品接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.marlowe.factory.abstract1;

/**
* @program: GoF23
* @description: 小米路由器
* @author: Marlowe
* @create: 2020-11-20 22:46
**/
public class XiaomiRouter implements IRouterProduct {
@Override
public void start() {
System.out.println("打开小米路由器");

}

@Override
public void shutdown() {
System.out.println("关闭小米路由器");
}

@Override
public void openWifi() {
System.out.println("打开小米路由器wifi");
}

@Override
public void setting() {
System.out.println("设置小米路由器");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.marlowe.factory.abstract1;

/**
* @program: GoF23
* @description: 华为路由器
* @author: Marlowe
* @create: 2020-11-20 22:46
**/
public class HuaweiRouter implements IRouterProduct {
@Override
public void start() {
System.out.println("打开华为路由器");

}

@Override
public void shutdown() {
System.out.println("关闭华为路由器");
}

@Override
public void openWifi() {
System.out.println("打开华为路由器wifi");
}

@Override
public void setting() {
System.out.println("设置华为路由器");
}
}

主类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.marlowe.factory.abstract1;

/**
* @program: GoF23
* @description: 客户端
* @author: Marlowe
* @create: 2020-11-21 11:01
**/
public class Client {
public static void main(String[] args) {
System.out.println("===============小米系列产品=================");
XiaomiFactory xiaomiFactory = new XiaomiFactory();
IPhoneProduct iPhoneProduct = xiaomiFactory.iPhoneProduct();
iPhoneProduct.call();
iPhoneProduct.sendMessage();

IRouterProduct iRouterProduct = xiaomiFactory.iRouterProduct();
iRouterProduct.openWifi();
System.out.println();

System.out.println("===============华为系列产品=================");
HuaweiFactory huaweiFactory = new HuaweiFactory();
iPhoneProduct = huaweiFactory.iPhoneProduct();
iPhoneProduct.call();
iPhoneProduct.sendMessage();

IRouterProduct iRouterProduct1 = huaweiFactory.iRouterProduct();
iRouterProduct1.openWifi();
}
}

1
2
3
4
5
6
7
8
9
10
结果:
===============小米系列产品=================
小米手机打电话
小米手机发信息
打开小米路由器wifi

===============华为系列产品=================
华为手机打电话
华为手机发信息
打开华为路由器wifi

适用场景:

  • 客户端(应用层)不依赖与产品类实例如何被创建、实现等细节
  • 强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复代码
  • 提供一个产品类的库,所有的产品以同样的接口出现,从而使得客户端不依赖于具体的实现

优点

  • 具体产品在应用层的代码隔离,无需关心创建的细节
  • 将一个系列的产品统一到一起管理

缺点

  • 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难
  • 增加了系统的抽象性和理解难度

小结

  1. 简单工厂模式(静态工厂模式)
    虽然某种程度上不符合设计原则,但实际使用最多!
  2. 工厂方法模式
    不修改已有类的前提下,通过新增新的工厂类实现扩展。
  3. 抽象工厂模式
    不可以增加产品,可以增加产品族!

评论