TypeScript 设计模式 - 抽象工厂模式

33 阅读1分钟

抽象工厂模式

创建一组相关的或相互依赖的对象,而无需指定它们的具体类。

示例

产品接口

// 产品 A 接口
interface Button {
    render(): void;
}

// 产品 B 接口
interface Checkbox {
    toggle(): void;
}
具体产品
// Windows 样式的具体产品
class WindowsButton implements Button {
    render(): void {
        console.log("Rendering Windows Button.");
    }
}

class WindowsCheckbox implements Checkbox {
    toggle(): void {
        console.log("Toggling Windows Checkbox.");
    }
}

// Mac 样式的具体产品
class MacButton implements Button {
    render(): void {
        console.log("Rendering Mac Button.");
    }
}

class MacCheckbox implements Checkbox {
    toggle(): void {
        console.log("Toggling Mac Checkbox.");
    }
}
抽象工厂
// 抽象工厂接口
interface GUIFactory {
    createButton(): Button;
    createCheckbox(): Checkbox;
}
具体工厂
// Windows 工厂
class WindowsFactory implements GUIFactory {
    createButton(): Button {
        return new WindowsButton();
    }

    createCheckbox(): Checkbox {
        return new WindowsCheckbox();
    }
}

// Mac 工厂
class MacFactory implements GUIFactory {
    createButton(): Button {
        return new MacButton();
    }

    createCheckbox(): Checkbox {
        return new MacCheckbox();
    }
}
客户端代码
// 客户端代码与工厂和产品接口交互
class Application {
    private button: Button;
    private checkbox: Checkbox;

    constructor(factory: GUIFactory) {
        this.button = factory.createButton();
        this.checkbox = factory.createCheckbox();
    }

    render(): void {
        this.button.render();
        this.checkbox.toggle();
    }
}

// 使用示例
function main(os: string) {
    let factory: GUIFactory;

    if (os === "Windows") {
        factory = new WindowsFactory();
    } else if (os === "Mac") {
        factory = new MacFactory();
    } else {
        throw new Error("Unsupported OS.");
    }

    const app = new Application(factory);
    app.render();
}

// 测试
main("Windows"); // 渲染 Windows 样式
main("Mac");     // 渲染 Mac 样式

关键点解析

  1. 抽象工厂:定义用于创建相关对象(ButtonCheckbox)的接口。
  2. 具体工厂:实现抽象工厂,生成具体产品。
  3. 产品接口和实现:每个产品(如 Button)定义自己的接口及多种实现(如 WindowsButtonMacButton)。
  4. 客户端代码解耦:通过依赖抽象工厂接口,客户端无需关心具体产品的类或创建逻辑。

应用场景

  • GUI 工具库:针对不同操作系统,提供不同风格的组件。
  • 数据库操作:针对不同数据库(如 MySQL、PostgreSQL)创建不同的连接对象。
  • 网络协议:根据不同协议(如 HTTP、FTP)创建不同的客户端。