设计模式GOF23--工厂模式

工厂模式:实现了创建者和调用者的分离

  • 详细分类:
    • 简单工厂模式
      • 虽然某种程度不符合设计原则,但实际使用最多
    • 工厂方法模式
      • 不修改已有类的前提下,通过增加新的工厂类实现扩展。
    • 抽象工厂模式
      • 不可以增加产品。可以增加产品族。

应用场景

  • JDK中Calendar的getInstance方法
  • JDBC中Connection对象的获取
  • Hibernate中SessionFactory创建Session
  • Spring中IOC容器创建管理bean对象
  • XML解析时DocumentBuilderFactory创建解析器对象
  • 反射中Class对象的newInstance();

面向对象的设计原则

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

普通方法

按照常理模式,当我们需要调用一个类的时候,我们需要通过new 一个对象来实现。那么,我在不知道工厂模式的情况下,多半是直接new,然后直接调用了。在此我就叫我的方法为普通方法。

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
42
43
44
45
46
47

/**
* 定义Car接口
*/
public interface Car {
void run();
}

/**
* 实现Car接口
* 比亚迪
*/
public class Byd implements Car{
@Override
public void run() {
System.out.println("比亚迪在跑");
}
}

/**
* 实现Car接口
* 奥迪
*/
public class Audi implements Car{

@Override
public void run() {
System.out.println("奥迪在跑");
}
}

/**
* 使用普通方法调用比亚迪和奥迪类
* 结果:
* 奥迪在跑
* 比亚迪再跑
*/
public class Client01 {
public static void main(String[] args) {
Car c1 = new Audi();
Car c2 = new Byd();

c1.run();
c2.run();

}
}

该方法虽然简单,但是显然没有使用遵循面向对象设计的基本原则嘛。为了提高自我代码的质量,还是要学习设计模式,并在日常编程中运用。

简单工厂模式

那么,要想提高,我们先来看一下简单工厂模式的类图:

如上图所示:
和我们的简单方法是不是差了点什么?没错,我们缺少CarFactory类。那我们先来看下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
/**
* 简单工厂类
* 缺点:不完全满足OCP
*/
public class CarFactory {
public static Car getCar(String type){
if ("奥迪".equals(type)){
return new Audi();
}else if ("比亚迪".equals(type)){
return new Byd();
}else {
return null;
}
}
}

/**
* 使用简单方法调用比亚迪和奥迪类
* 结果:
* 奥迪在跑
* 比亚迪再跑
*/
public class Client02 {
public static void main(String[] args) {
Car c1 = CarFactory.getCar("奥迪");
Car c2 = CarFactory.getCar("比亚迪");

c1.run();
c2.run();

}
}

在调用的时候,我们可以不必需要什么而new什么,我们只需要将参数传递过去,简单工厂会自动返回我们想要的对象。是不是灵活了很多!当然,这也就是所谓的找对象原则,我原先找对象,得自己找,苦苦的找,还不一定能找到。之后呢,出现这种找对象的平台了,我不用自己跑出去找了,我跟这个平台说一声,我想要长得好看的,个子高的,肤白貌美的。恩,这个平台就会给我找到。(ps:这个比喻忘记是看哪个仁兄的比喻,暂且借用。知道后标注。)这就是我们的工厂模式。

工厂方法模式

看了简单工厂,我们来了解下工厂方法模式:

  • 简单工厂模式只有一个工厂类,而工厂方法模式有一组实现了相同接口的工厂类。
  • 对比简单工厂模式:增加了工厂接口,通过不同的工厂类来实现工厂模式。如下图所示:

对比简单模式,我们增加了一个工厂接口,然后实现不同的工厂,这个时候,我们的调用者Client不需要知道Car的接口,只需要知道Car工厂的接口,就可以调用。是不是更加深层次的解耦代码了。这样有什么好处呢,假如我使用简单工厂模式,在我增加一个产品的时候,比如,我增加宝马,那Car的工厂类得进行修改。而使用工厂方法模式,那么我们只需要增加一个宝马的工厂类就行。但是,这样也有一个缺点,就是文件太多,不利于管理。

抽象工厂模式

  • 用来生产不同产品族的全部产品(对于增加的新的产品,无能为力;支持增加产品族)
  • 抽象工厂模式是工厂方法模式的升级版本,在由多个业务品种,业务分类时,通过抽象工厂模式需要的对象是一种非常好的解决方式。

    注:该博文为学习总结,视频来源为高淇java300集