Skip to content

工厂模式 (Factory Pattern)

什么是工厂模式?

工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,而是通过使用一个共同的接口来指向新创建的对象。

工厂模式的三种形态

1. 简单工厂模式(Simple Factory)

严格来说不算设计模式,更像是一种编程习惯。通过一个工厂类根据参数决定创建哪种产品。

java
/**
 * 抽象产品
 * @author yjhu
 */
interface Shape {
    void draw();
}

/**
 * 具体产品:圆形
 */
class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制圆形");
    }
}

/**
 * 具体产品:矩形
 */
class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制矩形");
    }
}

/**
 * 简单工厂
 * @author yjhu
 */
public class SimpleShapeFactory {
    public static Shape createShape(String type) {
        return switch (type.toLowerCase()) {
            case "circle" -> new Circle();
            case "rectangle" -> new Rectangle();
            default -> throw new IllegalArgumentException("未知的形状类型: " + type);
        };
    }
}

// 使用示例
Shape circle = SimpleShapeFactory.createShape("circle");
circle.draw();  // 输出: 绘制圆形

2. 工厂方法模式(Factory Method)

定义一个创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

java
/**
 * 抽象工厂
 * @author yjhu
 */
interface ShapeFactory {
    Shape createShape();
}

/**
 * 具体工厂:圆形工厂
 */
class CircleFactory implements ShapeFactory {
    @Override
    public Shape createShape() {
        return new Circle();
    }
}

/**
 * 具体工厂:矩形工厂
 */
class RectangleFactory implements ShapeFactory {
    @Override
    public Shape createShape() {
        return new Rectangle();
    }
}

// 使用示例
ShapeFactory factory = new CircleFactory();
Shape shape = factory.createShape();
shape.draw();  // 输出: 绘制圆形

3. 抽象工厂模式(Abstract Factory)

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

java
/**
 * 抽象产品:按钮
 */
interface Button {
    void render();
}

/**
 * 抽象产品:输入框
 */
interface Input {
    void render();
}

/**
 * 具体产品:Windows 风格
 */
class WindowsButton implements Button {
    @Override
    public void render() {
        System.out.println("渲染 Windows 风格按钮");
    }
}

class WindowsInput implements Input {
    @Override
    public void render() {
        System.out.println("渲染 Windows 风格输入框");
    }
}

/**
 * 具体产品:Mac 风格
 */
class MacButton implements Button {
    @Override
    public void render() {
        System.out.println("渲染 Mac 风格按钮");
    }
}

class MacInput implements Input {
    @Override
    public void render() {
        System.out.println("渲染 Mac 风格输入框");
    }
}

/**
 * 抽象工厂
 * @author yjhu
 */
interface GUIFactory {
    Button createButton();
    Input createInput();
}

/**
 * 具体工厂:Windows 工厂
 */
class WindowsFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new WindowsButton();
    }
    
    @Override
    public Input createInput() {
        return new WindowsInput();
    }
}

/**
 * 具体工厂:Mac 工厂
 */
class MacFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new MacButton();
    }
    
    @Override
    public Input createInput() {
        return new MacInput();
    }
}

// 使用示例
GUIFactory factory = new MacFactory();
Button button = factory.createButton();
Input input = factory.createInput();
button.render();  // 输出: 渲染 Mac 风格按钮
input.render();   // 输出: 渲染 Mac 风格输入框

适用场景

  • 简单工厂:产品种类较少,且不会频繁增加新产品。
  • 工厂方法:需要灵活扩展产品种类,遵循开闭原则。
  • 抽象工厂:需要创建一系列相关的产品族(如跨平台 UI 组件)。

三种工厂模式对比

模式复杂度扩展性适用场景
简单工厂差(违反开闭原则)产品种类少且固定
工厂方法好(新增产品只需新增工厂类)单一产品族,需要扩展
抽象工厂好(产品族级别扩展)多个产品族,跨平台系统

实际应用

  • JDKCalendar.getInstance()NumberFormat.getInstance()
  • SpringBeanFactoryFactoryBean
  • 日志框架LoggerFactory.getLogger()