设计模式(二)简单工厂模式

工厂模式是最常用的一类创建型设计模式,分为:简单工厂模式、工厂方法模式、抽象工厂模式三种。通常我们所说的工厂模式是指工厂方法模式,它也是使用频率最高的工厂模式。本文介绍的是最为简单的“简单工厂模式”。

简单工厂模式(Simple Factory Pattern):定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。因为在简单工厂模式中用于创建实例的方法是静态(static)方法,因此简单工厂模式又被称为静态工厂方法(Static Factory Method)模式。

举个例子:

使用简单工厂模式设计一个可以创建不同几何形状(如圆形、方形和三角形等)的绘图 工具,每个几何图形都具有绘制draw()和擦除erase()两个方法,要求在绘制不支持的几何 图形时,提示一个UnSupportedShapeException。
首先定义形状的抽象类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package info.aviraer.design_pattern.simple_factory;

/**
* 形状基类
* @author Aviraer
*
*/
public abstract class Shape {

/**
* 绘制形状
*/
public abstract void draw();

/**
* 擦除形状
*/
public abstract void erase();

}

然后用不同的形状类实现该抽象类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package info.aviraer.design_pattern.simple_factory;

/**
* 圆形
* @author Aviraer
*
*/
public class Circular extends Shape{

@Override
public void draw() {
System.out.println("Circular draw.");
}

@Override
public void erase() {
System.out.println("Circular erase.");
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package info.aviraer.design_pattern.simple_factory;

/**
* 三角形
* @author Aviraer
*
*/
public class Triangle extends Shape{

@Override
public void draw() {
System.out.println("Triangle draw.");
}

@Override
public void erase() {
System.out.println("Triangle erase.");
}

}

如果尝试用工厂创建其他的形状时,会抛出UnSupportedShapeException:

1
2
3
4
5
6
7
8
9
10
11
12
package info.aviraer.design_pattern.simple_factory;

public class UnSupportedShapeException extends RuntimeException{

private static final long serialVersionUID = 1L;

@Override
public String getMessage() {
return "Unsupported shape!";
}

}

接下来实现工厂方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package info.aviraer.design_pattern.simple_factory;

/**
* 形状简单工厂
* @author Aviraer
*
*/
public class ShapeFactory {

public static Shape getShape(String type){
Shape shape;
if ("circular".equals(type)){
shape = new Circular();
}else if ("triangle".equals(type)){
shape = new Triangle();
}else{
throw new UnSupportedShapeException();
}
return shape;
}

}

最后实现main方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package info.aviraer.design_pattern.simple_factory;

public class App {

public static void main(String[] args) {
Shape shape1 = ShapeFactory.getShape("circular");
shape1.draw();
shape1.erase();
Shape shape2 = ShapeFactory.getShape("triangle");
shape2.draw();
shape2.erase();
Shape shape3 = ShapeFactory.getShape("rectangle");
shape3.draw();
shape3.erase();
}

}

从上面的程序可以看出,简单工厂的

优势在于:

1.客户端可以直接使用产品而不需要关心产品创建的细节,实现了产品使用和创建的分离。

2.如果进一步将参数“type”放到配置文件中可以使得产品创建更加灵活。

劣势在于:

1.工厂类的职责过重。需要包含所有类型的创建方法。

2.系统复杂度增加。增加了工厂类。

3.扩展困难。产品的变动可能导致工厂类随之变动。

4.静态方法无法继承。使用静态工厂方法导致无法被继承。

应用场景:

1.产品类型较少。不会造成工厂类过于复杂。

2.客户不关心产品创建。所有创建工作交给工厂类。