工厂方法

概述

定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

当系统准备为用户提供某个类的子类的实例,又不想让用户代码和该子类形成耦合时,就可以使用工厂方法来设计系统。工厂方法的关键是在一个接口或抽象类中定义一个抽象方法,该方法返回某个类的子类的实例,该抽象类或接口让让其子类或实现该接口的类通过重写这个抽象方法返回某个子类的实例。

结构与使用

工厂方法模式中包含四种角色:

  • 抽象产品(Product):抽象类或接口,负责定义具体产品必须实现的方法。

  • 具体产品(ConcreteProduct):具体产品是一个类,如果 Product 是一个抽象类,那么具体产品是 Product 的子类;如果 Product 是一个接口,那么具体产品是实现 Product 接口的类。

  • 构造者(Creator):一个接口或抽象类。构造者负责定义一个称作工厂方法的抽象方法,该方法返回具体产品类的实例。

  • 具体构造者(ConcreteCreator):具体构造者重写工厂方法,使该方法返回具体产品的实例。

UML 类图

factoryMethod.jpg

结构的描述

比如,有一个 PenCore 类(笔芯),该类是一个抽象类。假设 PenCore 有三个子类,分别是 RedPenCore 类(红笔芯)和 BluePenCore 类(蓝笔芯),而系统设计的目的是为用户提供的 BallPen 类(圆珠笔)的子类的实例,即含有笔芯的圆珠笔,也就是说系统想让用户使用 BallPen 类的子类的实例来得到 PenCore 类的子类的实例。

1.抽象产品

1
2
3
4
public abstract class PenCore {
String color;
public abstract void writeWord(String s);
}

2.具体产品

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// RedPenCore.java
public class RedPenCore extends PenCore {
public RedPenCore() {
color = "红色";
}
@Override
public void writeWord(String s) {
System.out.println("写出" + color + "的字:" + s);
}
}

// BluePenCore.java
public class BluePenCore extends PenCore {
public BluePenCore() {
color = "绿色";
}
@Override
public void writeWord(String s) {
System.out.println("写出" + color + "的字:" + s);
}
}

3.构造者

1
2
3
4
5
6
public abstract class BallPen {
public BallPen() {
System.out.println("生产一支装有" + getPenCore().color + "笔芯的圆珠笔");
}
public abstract PenCore getPenCore();
}

4.具体构造者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// RedBallPen.java
public class RedBallPen extends BallPen {
@Override
public PenCore getPenCore() {
return new RedPenCore();
}
}

// BlueBallPen.java
public class BlueBallPen extends BallPen {
@Override
public PenCore getPenCore() {
return new BluePenCore();
}
}

5.模式的使用

1
2
3
4
5
6
7
8
9
public static void main(String[] args) {
PenCore penCore;
BallPen ballPen = new BlueBallPen();
penCore = ballPen.getPenCore();
penCore.writeWord("hello, nice to meet you");
ballPen = new RedBallPen();
penCore = ballPen.getPenCore();
penCore.writeWord("How are you ");
}

Java集合框架与工厂模式

Java 集合框架中有一个重要的接口 Collection ,该接口中的 iterator() 方法就是一个工厂方法。iterator() 方法返回一个实现 Iterator 接口类的实例。按照工厂模式的角色分类,Iterator 接口是抽象角色;Collection 接口是构造者;而实现Collection 接口的类,即集合,都是具体构造者,比如 LinkedList 链表类就是一个具体构造者。
集合框架中的工厂方法.jpg

1
2
3
4
5
6
7
8
9
10
public static void main(String[] args) {
Collection<Integer> mylist = new LinkedList<Integer>();
for (int i = 0; i < 10; i++) {
mylist.add(new Integer(i));
}
Iterator<Integer> iter = mylist.iterator();
while (iter.hasNext()) {
System.out.println(iter.next());
}
}

优点

  • 使用工厂方法可以使得用户的代码和某个特定类的子类的代码解耦。

  • 工厂方法使用户不需要知道他所使用的对象是如何被创建的,只需要知道该对象有哪些方法即可。

欢迎关注我的其它发布渠道