BrightLoong's Blog

设计模式——工厂模式

factory

一.概述

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一,其通过提供对象创建工厂,将创建对象的具体过程屏蔽起来,使调用的客户端不用关心具体的对象创建过程,提高了灵活性。

工厂模式属于创建型模式。

工厂模式根据抽象层的不用,可以分为以下三类:

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

其中“简单工厂模式”并不属于设计模式的一种,通俗的说是一种编程经验。

二. 简单工厂模式

简单工厂模式是工厂对象根据传入的参数不同,创建不同的对象实例。

UML类图解析

SimpleFactory

  • Product:产品接口,也可以是抽象类。
  • ProductA,ProductB:具体产品实现。
  • Factory:根据传入的参数创建具体的产品的工厂,供客户端调用。

代码实现

图形接口定义
1
2
3
4
5
6
7
8
package io.github.brightloong.design.factory;

/**
* Created by BrightLoong on 2018/5/5.
*/
public interface Shap {
void draw();
}
图形实现——Circle
1
2
3
4
5
6
7
8
9
10
package io.github.brightloong.design.factory;

/**
* Created by BrightLoong on 2018/5/5.
*/
public class Circle implements Shap{
public void draw() {
System.out.println("it is a circle");
}
}
图形实现——Square
1
2
3
4
5
6
7
8
9
10
package io.github.brightloong.design.factory;

/**
* Created by BrightLoong on 2018/5/5.
*/
public class Square implements Shap {
public void draw() {
System.out.println("it is a square");
}
}
工厂

关于工厂,最简单的是传入一个参数,使用 if, else或者case做条件判断返回不同的产品实现,也可以使用反射的方法,来消除这些判断条件。

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
package io.github.brightloong.design.factory;

/**
* Created by BrightLoong on 2018/5/5.
*/
public class SimpleShapFactory {
public Shap create(String shapType) {
if ("circle".equals(shapType)) {
return new Circle();
} else if ("square".equals(shapType)) {
return new Square();
}
return null;
}

/**
* 可以使用这种方式消除if之类的条件判断
* @param clz
* @param <T>
* @return
*/
public <T> Shap create(Class<T> clz) {
Shap shap = null;
try {
shap = (Shap) clz.newInstance();
} catch (InstantiationException e) {
return null;
} catch (IllegalAccessException e) {
return null;
}
return shap;
}
}
客户端调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package io.github.brightloong.design.factory;

/**
* Created by BrightLoong on 2018/5/5.
*/
public class Client1 {
public static void main(String[] args) {
Shap shap = new SimpleShapFactory().create("circle");
if (shap != null) {
shap.draw();
}

Shap shap1 = new SimpleShapFactory().create(Square.class);
if (shap1 != null) {
shap1.draw();
}
}
}

输出结果

1
2
it is a circle
it is a square

优点

  • 隐藏了具体的对象创建细节,提高了灵活性。
  • 便于扩展,添加新的产品时候只需要添加一个新的产品类,修改工厂。

缺点

  • 每添加一个新的产品都要修改工厂类在其中添加判断分支(如果没有用反射的方式),违反了开放-封闭原则。
  • 如果添加的产品过多会导致类膨胀。

三. 工厂方法模式

工厂方法模式除了对产品类的抽象外,又添加了对工厂的抽象,不再在工厂中进行调用逻辑的判断处理,而是将这个判断放在了客户端。工厂方法针对每一产品都提供一个工厂类,不同的工厂创建不同的产品实例。

UML类图解析

factoryMethod

工厂方法模式和简单工厂类似,不同的就是这里对工厂进行了抽象,有了一个抽象的工厂角色——AbstarctFactory。

代码实现

产品实现和简单工厂模式的一样,这里不再给出。

AbstractFactory——FactoryMethod
1
2
3
4
5
6
7
8
package io.github.brightloong.design.factory;

/**
* Created by BrightLoong on 2018/5/5.
*/
public abstract class FactoryMethod {
abstract Shap createShap();
}
FactoryA——CircleFactory
1
2
3
4
5
6
7
8
9
10
package io.github.brightloong.design.factory;

/**
* Created by BrightLoong on 2018/5/5.
*/
public class CircleFactory extends FactoryMethod {
public Shap createShap() {
return new Circle();
}
}
FactoryB——SquareFactory
1
2
3
4
5
6
7
8
9
10
package io.github.brightloong.design.factory;

/**
* Created by BrightLoong on 2018/5/5.
*/
public class SquareFactory extends FactoryMethod {
public Shap createShap() {
return new Square();
}
}
客户端调用
1
2
3
4
5
6
7
8
9
10
11
package io.github.brightloong.design.factory;

/**
* Created by BrightLoong on 2018/5/5.
*/
public class Client2 {
public static void main(String[] args) {
Shap shap = new SquareFactory().createShap();
shap.draw();
}
}

输出

1
it is a square

优点

  • 拥有简单工厂模式的优点。
  • 具有简单工厂模式的优点,并且再此基础上满足了开放-封闭原则,系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了。这样,系统的可扩展性也就变得非常好,完全符合“开闭原则”。

缺点

  • 随着产品类的增加,要提供与其对应的子类,系统中类个数成对增加,在一定程度上增加了系统的复杂性。

四. 抽象工厂模式

上面说道的简单工厂和工厂模式都只能创建一个产品实例,抽象工厂提供了生成多产品的功能。这里很多地方提到了产品族 的说法,比如生产面包的工厂不止生产面包,还会生产饼干、糖果之类的。

UML类图解析

factoryMethod

这里有ProductA和ProductB两个产品抽象,并且分别有两个具体实现,抽象工厂AbstractFactory和之前不同的是这里提供了两个生产产品的方法——crateProductA和crateProductB。

代码实现

在之前Shap产品的基础上增加Colro产品,具体代码如下:

Color
1
2
3
public interface Color {
void fill();
}
Color实现——Red
1
2
3
4
5
6
7
public class Red implements Color {

@Override
public void fill() {
System.out.println("it is red.");
}
}
Color实现——Green
1
2
3
4
5
6
7
public class Green implements Color {

@Override
public void fill() {
System.out.println("it is green");
}
}
抽象工厂—— AbstractFactory
1
2
3
4
public abstract class AbstractFactory {
abstract Color createColor();
abstract Shape createShape() ;
}
工厂实现1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package io.github.brightloong.design.factory;

/**
* Created by BrightLoong on 2018/5/5.
*/
public class RedCircleFactory extends AbstractFactory {
Shap createShap() {
return new Circle();
}

Color createColor() {
return new Red();
}
}
工厂实现2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package io.github.brightloong.design.factory;

/**
* Created by BrightLoong on 2018/5/5.
*/
public class GreenSquareFactory extends AbstractFactory {
Shap createShap() {
return new Square();
}

Color createColor() {
return new Green();
}
}
客户端调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package io.github.brightloong.design.factory;

/**
* Created by BrightLoong on 2018/5/2.
*/
public class Client3 {
public static void main(String[] args) {
AbstractFactory factory = new RedCircleFactory();
Shap shap = factory.createShap();
Color color = factory.createColor();
shap.draw();
color.fill();
}
}

输出

1
2
it is a circle
it is red.

优点

  • 支持了不同类型的产品,更加灵活。

缺点

  • 缺点很明显,类膨胀越来越厉害。
坚持原创技术分享,您的支持将鼓励我继续创作!