Java设计模式—工厂模式

如果对象的构造过程很长很复杂,将所有的初始化代码放在构造函数中是很危险的。把对象的创建过程抽象出来,这时候就需要用到工厂模式。将现实中的工厂与工厂模式联系起来,去理解工厂模式,就很容易了。

工厂模式可分为三类:

1. 简单工厂模式(Simple Factory Pattern)

2. 工厂方法模式(Factory Method Pattern)

3. 抽象工厂模式(Abstract Factoey Pattern)

一、简单工厂模式

简单工厂模式又称为静态工厂方法模式,属于创建型模式。简单工厂模式就是由一个工厂对象决定产生某个产品类的实例,它定义了一个用于创建对象的接口。

组成:

a. 工厂(Creator)角色,该模式的核心,负责所有创建实例的逻辑。

b. 抽象产品(Product)角色,所创建的所有对象的父类,描述所有实例的公共接口。

c. 具体产品(Concrete Product)角色,工厂类创建的对象是这个角色的实例。

代码示例:

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
package co.lujun.simplefactory;
/**
* Created by lujun on 2015/8/31.
*/
public class SimpleFactory {//工厂角色
public Car createCar(String name){
return new Factory().create(name);
}
public class Factory{
public Car create(String name){
Car car = null;
try{
car = (Car) Class.forName("co.lujun.simplefactory." + name).newInstance();
}catch (InstantiationException e){
e.printStackTrace();
}catch (IllegalAccessException e){
e.printStackTrace();
}catch (ClassNotFoundException e){
e.printStackTrace();
}
return car;
}
}
public interface Car {//抽象产品角色
void start();
void stop();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package co.lujun.simplefactory;
import android.util.Log;
/**
* Created by lujun on 2015/8/31.
*/
public class Audi implements SimpleFactory.Car {//具体产品角色
private final static String TAG = "tag";
@Override
public void start() {
Log.i(TAG, "Audi is start.");
}
@Override
public void stop() {
Log.i(TAG, "Audi is stop.");
}
}

测试:

1
2
3
4
5
6
SimpleFactory factory = new SimpleFactory();
SimpleFactory.Car car = factory.createCar("Audi");
if (car != null){
car.start();
car.stop();
}

output:

1
2
Audi is start.
Audi is stop.

以上的实例简单的实现了简单工厂模式,代码很简单,不多讲解。

二、工厂方法模式

工厂方法模式的定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。

组成:

a. 抽象工厂(Creator)角色,该模式的核心,提供所有具体工厂类的所有接口。

b. 具体工厂(Concrete Creator)角色,实现抽象工厂的具体工厂类,负责所有创建实例的逻辑。

c. 抽象产品(Product)角色,所创建的所有对象的父类,描述所有实例的公共接口或共同父类。

d. 具体产品(Concrete Product)角色,工厂类创建的对象是这个角色的实例,实现抽象产品的所有接口或继承它。

代码示例:

1
2
3
4
5
6
7
8
package co.lujun.factorymethod;
/**
* Created by lujun on 2015/8/31.
*/
public abstract class FactoryMethod {//抽象工厂角色
abstract Car create();
}
1
2
3
4
5
6
7
8
9
10
11
12
package co.lujun.factorymethod;
/**
* Created by lujun on 2015/8/31.
*/
public class AudiFactory extends FactoryMethod {//具体工厂角色
@Override
public Car create() {
return new Audi();
}
}
1
2
3
4
5
6
7
8
package co.lujun.factorymethod;
/**
* Created by lujun on 2015/8/31.
*/
public interface Car {//抽象产品角色
void run();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package co.lujun.factorymethod;
import android.util.Log;
/**
* Created by lujun on 2015/8/31.
*/
public class Audi implements Car {//具体产品角色
private final static String TAG = "tag";
@Override
public void run() {
Log.i(TAG, "Audi is run!");
}
}

类似,我们还可以创建Benz、BenzFactory,Toyota、ToyotaFactory,一个具体对象对应一个具体工厂对象,这样,当有新产品加入时,就不需要改动简单工厂模式中的工厂角色。

测试:

1
2
3
4
5
6
7
8
9
AudiFactory audiFactory = new AudiFactory();
Car audi = audiFactory.create();
audi.run();
BenzFactory benzFactory = new BenzFactory();
Car benz = benzFactory.create();
benz.run();
ToyotaFactory toyotaFactory = new ToyotaFactory();
Car toyota = toyotaFactory.create();
toyota.run();

output:

1
2
3
Audi is run!
Benz is run!
Toyota is run!
当只需要一个工厂类时,可以将抽象工厂角色与具体工厂角色合并,这样,就成了第一种讲述的简单工厂模式。
三、抽象工厂模式

抽象工厂模式与工厂方法模式类似,但是在抽象工厂模式中,抽象产品种类可能是一种或多种,从而构成一个或多个产品族,一族产品可以分不同的等级。英文陈述:Provide an interface for creating families of related or dependent objects without specifying their concrete classes(为创建一组或相互依赖的对象提供一组接口,而不用指明它们的具体类)。

组成和工厂方法模式相同。

示例代码:

1
2
3
4
5
6
7
8
9
package co.lujun.abstractfactory;
/**
* Created by lujun on 2015/8/31.
*/
public abstract class AbstractFactory {//抽象工厂,两个产品族
public abstract Car createCar();
public abstract People createPeople();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package co.lujun.abstractfactory;
/**
* Created by lujun on 2015/8/31.
*/
public class Factory extends AbstractFactory {//具体工厂
@Override
public Car createCar() {
return new Audi();
}
@Override
public People createPeople() {
return new Student();
}
}
1
2
3
4
5
6
7
8
package co.lujun.abstractfactory;
/**
* Created by lujun on 2015/8/31.
*/
public interface People {//抽象产品角色
void speak();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package co.lujun.abstractfactory;
import android.util.Log;
/**
* Created by lujun on 2015/8/31.
*/
public class Student implements People {//具体产品角色
private final static String TAG = "tag";
@Override
public void speak() {
Log.i(TAG, "I'm a student!");
}
}

同样,也可以创建Car、Audi等相对应的抽象产品和具体产品。一个具体工厂构造一族产品,不同的具体工厂用于完成不同等级的同中产品的构造

测试:

1
2
3
Factory factory = new Factory();
factory.createCar().run();
factory.createPeople().speak();

output:

1
2
Audi is run!
I'm a student!

在只有一个产品族(类似上面工厂方法模式中的Car族)的情况下,抽象工厂模式实际上退化到工厂方法模式。

四、总结

1. 简单工厂模式对于代码简单,易构造的对象来说很适用,可以动态的实例化相关类。

2. 工厂方法模式首先完全实现”开闭“原则,实现了可扩展;更复杂的层次结构,可以应用于产品结果复杂的场合。

3. 抽象工厂模式可以用于创建一族产品,而这族产品分不同的等级。相对工厂方法模式来说,具体工厂可以产生多种产品。

示例代码:https://gitlab.com/lujun/FactoryPatternDemo

参考:http://www.cnblogs.com/forlina/archive/2011/06/21/2086114.html