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 { static createAnimal(type: AnimalType): Animal { switch (type) { case AnimalType.Cat: return new Cat(); case AnimalType.Dog: return new Dog(); default: throw new Error("unsupported animal type"); } } } const cat = AnimalFactory.createAnimal(AnimalType.Cat); const dog = AnimalFactory.createAnimal(AnimalType.Dog); cat.sound(); dog.sound();Estoy tratando de mejorar en el principio abierto-cerrado y estoy tratando de descubrir cómo evitar el uso de declaraciones de cambio y desacoplar la clase de fábrica con la enumeración cuando agrego más subclases de Animal. El usuario a través de una API está enviando qué animal se creará a través de una enumeración simple. ¿Es posible modificar AnimalFactory de manera que no necesite modificar la clase de fábrica cada vez que agrego otro valor de enumeración y subclase de Animal?
¿Me equivoco y necesito más que una enumeración para usar como argumento?
Puede definir una constante que contenga una asignación de valores de enum a tipos de clase y usar un tipo asignado para crear una asignación de tipos:
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, } const animals = { [AnimalType.Cat]: Cat, [AnimalType.Dog]: Dog }; type Animals = { [A in keyof typeof animals]: InstanceType<typeof animals[A]> }; class AnimalFactory { static createAnimal<A extends keyof Animals>(type: A): Animals[A] { return new animals[type](); } } const cat = AnimalFactory.createAnimal(AnimalType.Cat); const dog = AnimalFactory.createAnimal(AnimalType.Dog); cat.sound(); dog.sound();Véalo en el patio de recreo