javascript - Typescript továreň trieda, ktorá sa vyhýba používaniu switch výrazu pri použití enumu ako vstupu?
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();
Odkaz na ihrisko
Snažím sa zlepšiť v princípe Open-Closed a snažím sa prísť na to, ako sa vyhnúť používaniu switch výrokov a odpojiť triedu factory od enumerácie, keď pridám ďalšie podtriedy triedy Animal. Používateľ cez API posiela, aké zviera sa má vytvoriť, pomocou jednoduchej enumerácie. Je možné upraviť AnimalFactory tak, aby som nemusel meniť triedu factory vždy, keď pridám ďalšiu hodnotu enumerácie a podtriedu Animal?
Idem na to nesprávne a potrebujem niečo viac ako enum, ktorý by som použil ako argument?
Odpoveď č. 1
Môžete definovať konštantu, ktorá obsahuje mapovanie hodnôt enum na typy tried, a použiť mapovaný typ na vytvorenie mapovania typov:
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();
Pozri sa na to na ihrisku
