工厂模式(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类;
public class Shape {
public double getPerimeter(){ return 0.0; }
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类;
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类;
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类;
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;
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;
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.*;
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 不同的产品需要不同额外参数的时候 不支持。