工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

注意事项:作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。

实现

步骤一

创建一个Shape父类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package class;

/**
* @author zhang
* @date 2020/7/23 14:30
*/
//形状类
public class Shape {
/**
* 得到周长
* @return
*/
public double getPerimeter(){
return 0.0;
}

/**
* 获得面积
* @return
*/
public double getArea(){
return 0.0;
}
}

步骤二

创建圆形子类继承Shape类

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
34
35
36
37
38
39
40
41
42
package class;

/**
* @author zhang
* @date 2020/7/24 14:56
*/
//圆形
public class Circle extends Shape{
private double radius;

public Circle() {
}

public Circle(double radius) {
this.radius = radius;
}

public double getRadius() {
return radius;
}

public void setRadius(double radius) {
this.radius = radius;
}

@Override
public String toString() {
return "Circle{" +
"radius=" + radius +
'}';
}

@Override
public double getArea() {
return Math.pow(radius,2) * Math.PI;
}

@Override
public double getPerimeter() {
return 2 * Math.PI * radius;
}
}

创建矩形子类

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package class;

/**
* @author zhang
* @date 2020/7/24 14:52
*/
//矩形
public class Rect extends Shape{
private double length;//长
private double width;//宽

public Rect() {
}

public Rect(double length, double width) {
this.length = length;
this.width = width;
}

public double getLength() {
return length;
}

public void setLength(double length) {
this.length = length;
}

public double getWidth() {
return width;
}

public void setWidth(double width) {
this.width = width;
}

@Override
public String toString() {
return "Rect{" +
"length=" + length +
", width=" + width +
'}';
}

@Override
public double getPerimeter() {
return 2 * (width + length);
}

@Override
public double getArea() {
return width * length;
}
}

创建正方形子类,间接继承Shape类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package class;

/**
* @author zhang
* @date 2020/7/24 14:56
*/
public class Square extends Rect{
private int bianchang;

public Square(int bianchang) {
super(bianchang,bianchang);
}

public Square(){
}

}

步骤三

创建一个工厂,生成基于给定信息的实体类的对象。

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
package class类.foactorydemo;

import class类.Circle;
import class类.Rect;
import class类.Shape;
import class类.Square;

/**
* @author zhang
* @date 2020/7/24 14:48
*/
public class ShapeFactory {
public static final int CIRCLE = 1;
public static final int RECT = 2;
public static final int SQUARE = 3;


public static Shape getInstance(int i){
Shape shape = null;
if (i == CIRCLE){
shape = new Circle();
}else if (i == RECT){
shape = new Rect();
}else if (i == SQUARE){
shape = new Square();
}else {
throw new RuntimeException("参数有误!");
}
return shape;
}
}

步骤四

使用该工厂,通过传递类型信息来获取实体类的对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package class类.foactorydemo;

import class类.Circle;
import class类.Shape;


/**
* @author zhang
* @date 2020/7/24 14:59
*/
public class TestFactory {
public static void main(String[] args) {
Shape shape = ShapeFactory.getInstance(ShapeFactory.CIRCLE);
System.out.println(shape instanceof Circle);
}
}

返回结果为true

更优雅的实现,将该类的所以静态资源导入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package class类.foactorydemo;

import class类.Circle;
import class类.Shape;
import static class类.foactorydemo.ShapeFactory.*;

/**
* @author zhang
* @date 2020/7/24 14:59
*/
public class TestFactory {
public static void main(String[] args) {
Shape shape = getInstance(CIRCLE);
System.out.println(shape instanceof Circle);
}
}

特点

1 它是一个具体的类,非接口 抽象类。有一个重要的getInstance()方法,利用if或者 switch创建产品并返回。

2 getInstance()方法通常是静态的,所以也称之为静态工厂。

缺点

1 扩展性差(我想增加一种面条,除了新增一个面条产品类,还需要修改工厂类方法)

2 不同的产品需要不同额外参数的时候 不支持。

评论