设计模式中的工厂模式。它属于创建型模式,那么什么是创建行模式呢,它主要就是将类或者对象的实例化过程抽象起来,可以分为类的创建型模式和对象的创建型模式两类,而工厂模式就属于对象的创建型模式。

工厂模式

简介

  工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。(通俗说就是工厂会根据不同的情况,为我们创建不同的产品。)

分类

  1)简单工厂模式 - Simple Factory Pattern
  2)工厂方法模式 - Factory Method Pattern
  3)抽象工厂模式 - Abstract Factory Pattern

  这三种模式从上到下逐步抽象,并且一个比一个更具有一般性。GoF 在《设计模式》一书中,将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。所以也有人将工厂模式分为两类,在这我更偏向把它分为三类,后面分三类举例讲解。

三种工厂模式用法

1、简单工厂模式:

  专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。它又称为静态工厂方法模式。它的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。

2、工厂方法模式:

  在工厂和产品中间增加接口,工厂不再负责产品的创建,由接口针对不同条件返回具体的类实例,由具体类实例去实现。有一个抽象的 Factory 类(可以是抽象类和接口),这个类将不在负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。

3、抽象工厂模式:

  抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。它有多个抽象产品类,每个抽象产品类可以派生出多个具体产品类,一个抽象工厂类, 可以派生出多个具体工厂类,每个具体工厂类可以创建多个具体产品类的实例。

代码演示

  看了上面的用法,大家可能有些不能理解,下面就用三个非常简单的栗子阐述清楚这些概念:

1、简单工厂模式例子

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
package simple;
/**
* 简单工厂模式:生产多种型号宝马产品
* 补充:开闭原则——>对扩展的开放,对修改的关闭
* 缺点:每增加一种新型车,工厂类中需要增加相应的case,违背开闭原则(对扩展的开发,对修改的关闭)
* 弥补:提出工厂方法模式,定义如下
* 工厂类定义成了接口,而每新增的车种类型,就增加该车种类型对应工厂类的实现,
* 这样工厂的设计就可以扩展了,而不必去修改原来的代码。
*/
//产品类
interface BMW{

}
class BMW320 implements BMW{
public BMW320() {
System.out.println("制造 BMW320");
}
}
class BMW523 implements BMW{
public BMW523() {
System.out.println("制造 BMW523");
}
}
//工厂类
class Factory{
public BMW createBMW(int type) { //根据参数不同,返回不同的产品(对象)
switch (type) {
case 320:
return new BMW320();
case 523:
return new BMW523();
default:
break;
}
return null;
}
}
//顾客类
public class Customer {
public static void main(String[] args) {
Factory factory = new Factory();
factory.createBMW(320);
factory.createBMW(523);
}
}

2、工厂方法模式例子

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
48
49
50
package method;
/**
* 工厂方法模式:生产多种型号宝马产品
* 缺点:如果要生产多个产品,此将不再适用
* 弥补:提出抽象工厂模式,特点如下
* 抽象工厂模式有多个抽象产品类,具体工厂类可以创建多个具体产品类的实例
*/
//产品类
interface BMW{

}
class BMW320 implements BMW{
public BMW320() {
System.out.println("生产BMW320");
}
}
class BMW523 implements BMW{
public BMW523() {
System.out.println("生产BMW523");
}
}
//工厂类
interface FactoryBMW{
public BMW createBWM();
}
class FactoryBMW320 implements FactoryBMW{
@Override
public BMW createBWM() { //父类作为方法返回值实现多态
// TODO Auto-generated method stub
return new BMW320(); //返回该工厂生产的产品
}
}
class FactoryBMW523 implements FactoryBMW{
@Override
public BMW createBWM() {
// TODO Auto-generated method stub
return new BMW523();
}
}
//客户类
public class Customer {
public static void main(String[] args) {
//创建320型号宝马的工厂
FactoryBMW320 factoryBMW320 = new FactoryBMW320();
factoryBMW320.createBWM();
//创建523型号宝马的工厂
FactoryBMW523 factoryBMW523 = new FactoryBMW523();
factoryBMW523.createBWM();
}
}

3、抽象工厂模式例子

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package ecjtu.mjh.abstr;
/**
* 抽象工厂模式:生产汽车的多种配件的多种型号产品
* 两个重要概念:
* 产品等级结构:产品的继承结构。
* 产品族:在抽象工厂模式中,产品族(Dough、Sauce)是指由同一个工厂生产的,
* 位于不同产品等级结构中的一组产品。
*/
//产品类
//产品1:引擎
interface Engine{

}
class EngineA implements Engine{
public EngineA() {
System.out.println("生产引擎A");
}
}
class EngineB implements Engine{
public EngineB() {
System.out.println("生产引擎B");
}
}
//产品2:轮胎
interface Tyre{

}
class TyreA implements Tyre{
public TyreA() {
System.out.println("生产轮胎A");
}
}
class TyreB implements Tyre{
public TyreB() {
System.out.println("生产轮胎B");
}
}
//工厂类
//抽象工厂接口
interface AbstractFactory{
public Engine createEngine();
public Tyre createTyre();
}
class FactoryBMW320 implements AbstractFactory{
//生产宝马320系列配件的工厂:需要引擎A和轮胎A
@Override
public Engine createEngine() {
// TODO Auto-generated method stub
return new EngineA();
}

@Override
public Tyre createTyre() {
// TODO Auto-generated method stub
return new TyreA();
}

}
class FactoryBMW523 implements AbstractFactory{
//生产宝马523系列配件的工厂:需要引擎B和轮胎B
@Override
public Engine createEngine() {
// TODO Auto-generated method stub
return new EngineB();
}

@Override
public Tyre createTyre() {
// TODO Auto-generated method stub
return new TyreB();
}

}
public class Customer {
public static void main(String[] args) {
//要生产宝马320的配件的工厂
FactoryBMW320 f320 = new FactoryBMW320();
f320.createEngine();
f320.createTyre();

//要生产宝马523的配件的工厂
FactoryBMW523 f523 = new FactoryBMW523();
f523.createEngine();
f523.createTyre();
}
}

工厂方法模式与抽象工厂模式的区别

  结合了上面的例子,看下面的区别就容易理解了
  1)工厂方法模式:
  一个抽象产品类,可以派生出多个具体产品类。
  一个抽象工厂类,可以派生出多个具体工厂类。
  每个具体工厂类只能创建一个具体产品类的实例。
  2)抽象工厂模式:
  多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
  一个抽象工厂类,可以派生出多个具体工厂类。
  每个具体工厂类可以创建多个具体产品类的实例。
  3)两者区别:
  工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
  工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。

适用场景和相互转换

  当需要创建的对象是一系列相互关联或相互依赖的产品族时,便可以使用抽象工厂模式。说的更明白一点,就是一个继承体系中,如果存在着多个等级结构(即存在着多个抽象类),并且分属各个等级结构中的实现类之间存在着一定的关联或者约束,就可以使用抽象工厂模式。
  明明使用的工厂方法模式,当新需求来临,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了;而对于抽象工厂模式,当减少一个方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。

总结

  在使用工厂模式时,只需要关心降低耦合度的目的是否达到了。解耦简单说就是让设计依赖于抽象(接口),而不是依赖于实现(具体的类)。打个比方,汽车制造者可以依赖于轮胎这个抽象的东西,但不能依赖于具体的品牌比如” 朝阳轮胎”。