设计模式二:工厂方法模式

含义

官方:定义一个用于创建对象的接口,让子类决定实例化哪一个类。

白话:建设一个工厂,客户需要什么产品,工厂都可以对应生产,而不需要关心生产过程。

UML类图

实现方式

以鞋厂生产不同类型的鞋子为例:

抽象产品类

1
2
3
4
5
6
public abstract class Shoes {
public abstract void color();
public abstract void size();
}

具体的产品类

继承于抽象产品类。

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
public class SportShoes extends Shoes {
@Override
public void color() {
System.out.println("红色的运动鞋。");
}
@Override
public void size() {
System.out.println("运动鞋的尺寸为43号。");
}
}
public class DressShoes extends Shoes {
@Override
public void color() {
System.out.println("黑色的皮鞋。");
}
@Override
public void size() {
System.out.println("皮鞋的尺寸为42号。");
}
}

抽象的工厂类

负责定义产品对象的产生。

1
2
3
4
public abstract class ShoesFactory {
public abstract <T extends Shoes> T createShoes(Class<T> c);
}

具体的工厂类

负责如何具体生产一个产品对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class ChineseShoesFactory extends ShoesFactory {
@Override
public <T extends Shoes> T createShoes(Class<T> c) {
Shoes shoes = null;
try {
//通过反射实例化对象
shoes = (Shoes) Class.forName(c.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return (T) shoes;
}
}

场景类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Client {
public static void main(String[] args) {
ShoesFactory factory = new ChineseShoesFactory();
Shoes sportShoes = factory.createShoes(SportShoes.class);
sportShoes.color();
sportShoes.size();
Shoes dressShoes = factory.createShoes(DressShoes.class);
dressShoes.color();
dressShoes.size();
}
}

简单工厂模式(静态工厂模式)

将上述抽象工厂类ShoesFactory去掉,然后将具体工厂类ChineseShoesFactory中的createShoes修改为静态方法,其余保持不变,这就是简单工厂模式。当模块仅需一个工厂类时,就不需要此处的抽象工厂类了,此时便可适用简单工厂模式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class ChineseShoesFactory {
public static <T extends Shoes> T createShoes(Class<T> c) {
Shoes shoes = null;
try {
//通过反射实例化对象
shoes = (Shoes) Class.forName(c.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return (T) shoes;
}
}

Android中的典型使用

BitmapFactory类就是一个比较常见的简单工厂模式的工厂类。

总结

工厂方法模式是new一个对象的替代品,在所有需要生成对象的地方都可以使用,但是需要慎重地考虑是否要增加一个工厂类进行管理,增加代码的复杂度。

优点:良好的封装性,高层模块只需要知道产品的抽象类即可,降低了模块间的耦合。
缺点:增加了代码的复杂度。

鸣谢参考:《设计模式之禅》、《Android源码设计模式解析与实践》






0%