目录
- 概括
- 目的
- 主要解决
- 何时使用
- 使用场景
- 总结
- 三种工厂模式的对比
- 代码示例
概括
定义一个用于创建对象的接口,让子类决定实例化哪一个类。使用特殊的工厂方法代替对于对象构造函数的直接调用(即使用 new运算符,工厂方法 使一个类的实例化延迟到其子类。)
目的
工厂方法的目的是使得创建对象和使用对象是分离的,并且客户端总是引用抽象工厂和抽象产品。
主要解决
主要解决接口选择的问题。
何时使用
我们明确地计划不同条件下创建不同实例时。
使用场景
作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。
总结
工厂方法,将多个具有相同功能(具体实现不相同)的不同类抽象为一个抽象类,并提供一个工厂方法代替对于对象构造函数的直接调用(只返回抽象类)。客户端通过工厂方法的参数指定具体的类型,将返回的具体类当抽象类使用(无需关心具体类的实现方式)。
工厂方法可以隐藏创建产品的细节,且不一定每次都会真正创建产品,完全可以返回缓存的产品,从而提升速度并减少内存消耗。
三种工厂模式的对比
三种工厂模式都封装了对象创建的过程,调用方通过抽象工厂获取抽象产品,调用方只使用抽象产品。
简单工厂:所有产品都由一个工厂创建,根据参数创建不同产品,因此每次添加新产品,都需要修改工厂的方法。
工厂方法:每个产品都有相应的工厂实现了,由调用方决定使用实例化哪个工厂。工厂方法的工厂用来创建一种产品(如:鼠标工厂创建鼠标、键盘工厂键盘)。
抽象工厂:工厂方法的增强,每个工厂可以创建一系列相关的产品(如小米工厂可以创建小米鼠标、小米键盘; 华为工厂可以创建华为鼠标,华为键盘)。可以认为抽象工厂是对工厂方法的组合。
代码示例
- 步骤一
创建一个接口
public interface Shape {void draw();}
- 步骤二
创建实现接口的实体类
public class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Inside Rectangle::draw() method.");}}public class Square implements Shape {@Overridepublic void draw() {System.out.println("Inside Square::draw() method.");}}javapublic class Circle implements Shape {@Overridepublic void draw() {System.out.println("Inside Circle::draw() method.");}}
- 步骤三
创建一个工厂,生成基于给定信息的实体类的对象。
public class ShapeFactory {//使用 getShape 方法获取形状类型的对象public Shape getShape(String shapeType){if(shapeType == null){return null;} if(shapeType.equalsIgnoreCase("CIRCLE")){return new Circle();} else if(shapeType.equalsIgnoreCase("RECTANGLE")){return new Rectangle();} else if(shapeType.equalsIgnoreCase("SQUARE")){return new Square();}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.