Abstract factory

by Artem

TypeScript

abstract class Herbivore {

}

abstract class Carnivore {
    public abstract eat(herbivore: Herbivore)
}

abstract class ContinentFactory {
    public abstract createCarnivore(): Carnivore;
    public abstract createHerbivore(): Herbivore;
}

class Bison extends Herbivore {

}

class Wolf extends Carnivore {
    public eat(herbivore: Herbivore) {
        console.log('Eating ' + herbivore);
    }
}

class Wildbeast extends Herbivore {

}

class Lion extends Carnivore {
    public eat(herbivore: Herbivore) {
        console.log('Eating ' + herbivore);
    }
}

class AmericaFactory extends ContinentFactory {
    public createHerbivore() {
        return new Bison();
    }
    public createCarnivore() {
        return new Wolf();
    }
}

class AfricaFactory extends ContinentFactory {
    public createHerbivore() {
        return new Wildbeast();
    }
    public createCarnivore() {
        return new Lion();
    }
}

class AnimalWorld {
    private herbivore: Herbivore;
    private carnivore: Carnivore;

    constructor(continentFactory: ContinentFactory) {
        this.herbivore = continentFactory.createHerbivore();
        this.carnivore = continentFactory.createCarnivore();
    }

    public runFoodChain(): void {
        this.carnivore.eat(this.herbivore);
    }
}

// Create and run African animal world
const africa: ContinentFactory = new AfricaFactory();
const africanWorld: AnimalWorld = new AnimalWorld(africa);
africanWorld.runFoodChain();


// Create and run American animal world
const america: ContinentFactory = new AmericaFactory();
const americanWorld: AnimalWorld = new AnimalWorld(america);
americanWorld.runFoodChain();