简单工厂模式

487 阅读4分钟

点击阅读:设计模式系列文章


1. 简单工厂模式定义

简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于一种创建型设计模式。它根据客户端传入的参数动态决定创建哪种具体产品类的实例,并返回其抽象类型

核心:专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类

解决的核心问题

  • 解耦创建与使用:客户端不需要直接 new 对象,只需通过工厂获取,避免了客户端代码与具体实现类的耦合。
  • 逻辑集中管理:将分散在各处的对象创建代码收拢到单一工厂中,便于统一维护(如修改初始化逻辑)

2. 简单工厂模式结构

2.1 Factory:工厂角色,负责创建具体产品的对象,只有它可以创建对象。

  • 职责:工厂角色,负责创建具体产品的对象,只有它可以创建产品对象
  • 核心方法:通常为static createXxx(),内含if-else/switch分支逻辑
  • 关键约束:需知晓所有具体产品类的创建细节

2.2 Product

  • 角色:所有具体产品的共同接口或父类
  • 作用:定义产品契约,使客户端能统一操作不同产品

2.3 ConcreteProduct

  • 角色:实现抽象产品接口的具体类
  • 关键点:所有具体产品必须实现统一接口

结构图: image.png

3. 简单工厂模式举例

设计一个程序,根据用户输入的形状名称画出对应形状图形,比如画出正方形和圆形。

定义一个形状接口 Shape,以及其具体实现类 Circle 和 Square。这时可以创建一个简单工厂类 ShapeFactory,它包含一个方法 createShape(String type),根据参数 type 创建不同的形状对象。

public interface Shape {
    void draw();
}

public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Inside Circle::draw() method.");
    }
}

public class Square implements Shape {
    @Override
    public void draw() {
        System.out.println("Inside Square::draw() method.");
    }
}

public class ShapeFactory {
    public Shape createShape(String type) {
        if ("circle".equalsIgnoreCase(type)) {
            return new Circle();
        } else if ("square".equalsIgnoreCase(type)) {
            return new Square();
        }
        return null;
    }
}

使用简单工厂模式,客户端可以像下面这样创建并使用形状对象,而不需要关心具体的创建细节:

ShapeFactory factory = new ShapeFactory();
Shape shape1 = factory.createShape("circle");
shape1.draw();

Shape shape2 = factory.createShape("square");
shape2.draw();

简单工厂模式可以帮助降低客户端和具体类之间的耦合度,使得代码更易于维护和扩展。

结构图: image.png

4. 简单工厂模式的优缺点

4.1 优点

  1. 隐藏对象创建细节:客户端不需要了解和处理对象的创建细节,只需通过工厂来获取对象。
  2. 集中化管理:通过工厂集中管理对象的创建过程,便于维护和修改。如果需要改变创建对象的逻辑,只需要修改工厂类而不影响客户端。
  3. 降低耦合度:客户端代码与具体类之间的耦合度降低,因为客户端只与工厂类交互而不直接依赖具体类的实例化过程。

4.2 缺点

  1. 扩展性受限:如果需要添加新的产品类型,通常需要修改工厂类的逻辑,违反了开闭原则。
  2. 责任过重:工厂类负责创建多种产品,导致工厂类代码可能会变得非常庞大。
  3. 违反单一职责原则:工厂类不仅负责对象的创建,还可能包括其它业务逻辑,违反了单一职责原则。
  4. 静态方法限制: 静态方法不支持多态,无法通过继承扩展行为

5. 应用场景与边界

适用场景:

  • 产品类型较少稳定(如不超过5种)
  • 客户端不关心创建过程,只需获得可用对象
  • 需要统一入口管理创建逻辑(如带缓存的对象创建)9

不适用场景:

  • 产品类型频繁变化(需反复修改工厂类)
  • 产品初始化逻辑复杂且各不相同(导致工厂代码臃肿)
  • 需要支持运行时动态扩展(插件化系统)

注:典型误用,当产品存在继承树层级差异时(如无共同父类),强行使用简单工厂会导致类型转换风险