课程大纲 / Lesson 02
Factory Method 创建型

Factory Method · 工厂方法

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

01

理解工厂方法模式:通过虚函数延迟对象创建到子类

02

掌握工厂方法的核心结构:Creator、ConcreteCreator、Product、ConcreteProduct

03

理解"依赖倒置原则"——Creator 依赖 Product 接口而非具体类

04

了解工厂方法与简单工厂的区别,以及何时应该使用它

核心概念
虚函数延迟创建依赖倒置原则开闭原则解耦 Creator 与 Product
classDiagram class button { <<interface>> +render() +onclick() } class htmlbutton { <<stateless>> +render() +onclick() } class windowsbutton { <<stateless>> +render() +onclick() } class dialog { <<abstract>> +createbutton() button +renderwindow() } class htmldialog { <<stateless>> +createbutton() button } class windowsdialog { <<stateless>> +createbutton() button } button <|.. htmlbutton button <|.. windowsbutton dialog <|-- htmldialog dialog <|-- windowsdialog htmldialog ..> htmlbutton : creates windowsdialog ..> windowsbutton : creates

创建者定义工厂方法,具体子类决定实例化哪一种产品

Click Run to see the dialog...
/** 产品接口:所有按钮实现此接口 */
public interface Button {
    void render();
    void onClick();
}
/** HTML 按钮实现 */
public class HtmlButton implements Button {

    public void render() {
        System.out.println("<button>Test Button</button>");
        onClick();
    }

    public void onClick() {
        System.out.println(
            "Click! Button says - \'Hello World!\'");
    }
}
/** Windows 风格按钮实现 */
public class WindowsButton implements Button {

    public void render() {
        System.out.println("[Windows Button]");
        onClick();
    }

    public void onClick() {
        System.out.println(
            "Click! Windows Button - \'Hello World!\'");
    }
}
/**
 * 基础创建者类。
 * renderWindow() 包含核心业务逻辑,
 * 需要 createButton() 创建产品。
 */
public abstract class Dialog {

    public void renderWindow() {
        Button okButton = createButton();
        okButton.render();
    }

    /** 子类重写此方法以创建具体按钮 */
    public abstract Button createButton();
}
/** HTML 对话框 → 产出 HTML 按钮 */
public class HtmlDialog extends Dialog {

    @Override
    public Button createButton() {
        return new HtmlButton();
    }
}
/** Windows 对话框 → 产出 Windows 按钮 */
public class WindowsDialog extends Dialog {

    @Override
    public Button createButton() {
        return new WindowsButton();
    }
}
public class Demo {
    private static Dialog dialog;

    public static void main(String[] args) {
        configure();
        runBusinessLogic();
    }

    /** 根据配置选择具体创建者 */
    static void configure() {
        if (System.getProperty("os.name")
                .equals("Windows 10")) {
            dialog = new WindowsDialog();
        } else {
            dialog = new HtmlDialog();
        }
    }

    /** 客户端通过抽象接口与所有创建者/产品工作 */
    static void runBusinessLogic() {
        dialog.renderWindow();
    }
}
◈

工厂方法不直接 new 对象

Creator 调用工厂方法,由子类决定创建哪个具体产品(new 的位置从业务代码转移到子类)。

◈

遵循开闭原则

新增产品(如 WebDialog 适配新平台)无需修改 Dialog,只需添加新子类。

◈

Creator 与 Product 解耦

Dialog.renderWindow() 只认识 Button 接口,不知道具体是 HtmlButton 还是 WindowsButton。

◈

适合需要子类决定创建场景

如:跨平台 UI(iOS/Android 按钮族)、数据库驱动、日志框架、文档生成器。