工厂模式
2021年7月15日大约 2 分钟约 636 字
1. 概念
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,而是通过使用一个共同的接口来指向新创建的对象,让子类决定实例化哪一个类,工厂模式使一个类的实例化延迟到其子类进行。
比如,你需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。
使用场景:
- 日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
- 数据库访问:当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。
- 设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。
java.util.Calendar
,ResourceBundle
,NumberFormat
的getInstance()
方法使用了工厂模式,此外valueOf()
在如Boolean
,Integer
的包装类中也使用了工厂模式。
2. 示例
我们将创建一个 Shape
接口,及一些实现 Shape
接口的实体类。然后创建一个工厂类 ShapeFactory
,最后令客户端类*FactoryPatternDemo
* 使用 ShapeFactory
来获取 Shape
对象。

创建接口:
public interface Shape { void draw(); }
创建实现接口的实体类:
public class Rectangle implements Shape { @Override public void draw() { System.out.println("Inside Rectangle::draw() method."); } }
public class Square implements Shape { @Override public void draw() { System.out.println("Inside Square::draw() method."); } }
public class Circle implements Shape { @Override public void draw() { System.out.println("Inside Circle::draw() method."); } }
创建一个工厂,生成基于给定信息的实体类的对象:
public class ShapeFactory { //使用 getShape 方法获取形状类型的对象 public Shape getShape(String shapeType){ if(shapeType.equalsIgnoreCase("CIRCLE")){ return new Circle(); } else if(shapeType.equalsIgnoreCase("RECTANGLE")){ return new Rectangle(); } else if(shapeType.equalsIgnoreCase("SQUARE")){ return new Square(); } else { return null; } } }
客户端使用该工厂,通过传递类型信息来获取实体类的对象:
public class FactoryPatternDemo { public static void main(String[] args) { ShapeFactory shapeFactory = new ShapeFactory(); //获取 Circle 的对象,并调用它的 draw 方法 Shape shape1 = shapeFactory.getShape("CIRCLE"); //调用 Circle 的 draw 方法 shape1.draw(); //获取 Rectangle 的对象,并调用它的 draw 方法 Shape shape2 = shapeFactory.getShape("RECTANGLE"); //调用 Rectangle 的 draw 方法 shape2.draw(); //获取 Square 的对象,并调用它的 draw 方法 Shape shape3 = shapeFactory.getShape("SQUARE"); //调用 Square 的 draw 方法 shape3.draw(); } }
// 程序输出结果 // Inside Circle::draw() method. // Inside Rectangle::draw() method. // Inside Square::draw() method.