You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript工厂类如何避免switch匹配enum以符合开闭原则

解决方案

首先明确:可以通过调整工厂的实现逻辑满足开闭原则,不需要修改工厂原有代码即可扩展新的动物子类,也可以根据实际场景选择是否保留枚举作为入参。

方案1:保留枚举入参,新增注册机制(适配API传枚举值的场景)

核心思路是给工厂类添加全局的类型-构造函数映射表,以及配套的注册方法,新增动物子类时只需要注册对应关系即可,不需要修改工厂原有创建逻辑。

优化后完整代码

abstract class Animal {
    abstract sound(): void;
}

class Cat extends Animal {
    sound(){
        console.log("meow");
    }
}

class Dog extends Animal {
    sound(){
        console.log("bark");
    }
}

enum AnimalType {
  Cat = 1,
  Dog = 2,
}

class AnimalFactory {
  // 存储枚举值到对应动物构造函数的映射
  private static animalConstructors = new Map<AnimalType, new () => Animal>();

  // 提供公开注册方法,新增动物时调用即可
  static register(type: AnimalType, constructor: new () => Animal) {
    this.animalConstructors.set(type, constructor);
  }

  static createAnimal(type: AnimalType): Animal {
    const constructor = this.animalConstructors.get(type);
    if (!constructor) {
      throw new Error("unsupported animal type");
    }
    return new constructor();
  }
}

// 初始化时注册现有动物类型
AnimalFactory.register(AnimalType.Cat, Cat);
AnimalFactory.register(AnimalType.Dog, Dog);

// 使用方式不变
const cat = AnimalFactory.createAnimal(AnimalType.Cat);
const dog = AnimalFactory.createAnimal(AnimalType.Dog);
cat.sound(); // 输出meow
dog.sound(); // 输出bark

扩展示例

如果后续要新增鸟类,只需要做三步,完全不需要修改AnimalFactory的原有代码:

  1. 新增Bird子类继承Animal
  2. 在AnimalType枚举中新增Bird = 3项
  3. 调用AnimalFactory.register(AnimalType.Bird, Bird)完成注册

方案2:移除枚举,直接传入构造函数作为入参(类型更安全,无需注册)

如果不需要适配API传枚举值的场景,直接用构造函数作为入参是更简洁的方案,天然符合开闭原则,新增子类不需要任何额外操作:

优化后完整代码

abstract class Animal {
    abstract sound(): void;
}

class Cat extends Animal {
    sound(){
        console.log("meow");
    }
}

class Dog extends Animal {
    sound(){
        console.log("bark");
    }
}

class AnimalFactory {
  static createAnimal<T extends Animal>(constructor: new () => T): T {
    return new constructor();
  }
}

// 使用方式
const cat = AnimalFactory.createAnimal(Cat);
const dog = AnimalFactory.createAnimal(Dog);
cat.sound();
dog.sound();

内容的提问来源于stack exchange,提问作者szebert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 05:48:04