Skip to content

Instantly share code, notes, and snippets.

@boxgames1
Last active April 22, 2022 06:40
Show Gist options
  • Save boxgames1/95ea88f202f36f55c70af70f0f2f2b13 to your computer and use it in GitHub Desktop.
Save boxgames1/95ea88f202f36f55c70af70f0f2f2b13 to your computer and use it in GitHub Desktop.
Observable pattern - Pizza Maker
const EventEmitter = require("events").EventEmitter;
class Pizza extends EventEmitter {
constructor(size = 1) {
super();
this.ovenTime = this._ovenTime(size);
this.maxIngredients = this._maxIngredients(size);
this.ingredients = [];
this.timeToReleasePizza = 5;
}
/**
* Static function that returns size types
*/
static sizes() {
return {
small: 1,
medium: 2,
familiar: 3
};
}
/**
* Max pizza ingredients by size
* @param {Number} size
* @returns {Number}
*/
_maxIngredients(size) {
return size * 3;
}
/**
* Oven time by size
* @param {Number} size
* @returns {Number}
*/
_ovenTime(size) {
return 5 + size * 2;
}
/**
* Checks if max number of ingredients was reached
* @returns {Boolean}
*/
_isMaxIngredientsReached() {
return this.ingredients.length === this.maxIngredients;
}
/**
* Adds and ingredient to pizza if max was
* not reached and emits events in both cases
* @param {String} ingredient
* @returns {Pizza}
*/
add(ingredient) {
if (!this._isMaxIngredientsReached()) {
this.ingredients.push(ingredient);
this.emit("ingredientAdded", ingredient);
} else {
this.emit("maxIngredientsReached");
}
return this;
}
/**
* Removes and ingredient from the pizza if founf
* and emits events in both cases
* @param {String} ingredient
* @returns {Pizza}
*/
remove(ingredient) {
const ingredientToRemove = this.ingredients.indexOf(ingredient);
if (ingredientToRemove !== -1) {
this.ingredients.splice(ingredientToRemove, 1);
this.emit("ingredientRemoved", ingredient);
} else {
this.emit("errorRemovingIngredient", ingredient);
}
return this;
}
/**
* It starts the timer once the oven time is passed,
* the pizza has to be released (clearing interval)
* in an specific amount of time to avoid charring
* @returns {Pizza}
*/
cook() {
this.emit("cookStarted");
setTimeout(() => {
const releasePizza = setTimeout(() => {
this.emit("charredPizza");
}, this.timeToReleasePizza);
this.emit("cookFinished", releasePizza);
}, this.ovenTime);
return this;
}
}
const createMediumPizza = () => {
const pizza = new Pizza(Pizza.sizes().medium);
pizza
.on("ingredientAdded", ing => console.log(`${ing} added`))
.on("maxIngredientsReached", ing =>
console.log(`Max ingredients (${pizza.maxIngredients}) reached`)
)
.on("ingredientRemoved", ing => console.log(`${ing} removed`))
.on("errorRemovingIngredient", ing =>
console.log(`Can not remove ${ing} because is not in the pizza`)
)
.on("cookStarted", () => console.log("Pizza is in the oven."))
.on("cookFinished", release => {
console.log(`Pizza is ready to release.`);
clearTimeout(release);
console.info("Pizza was released!");
})
.add("Tomato")
.add("Mushrooms")
.add("Scarmoza")
.add("Bone")
.remove("Bone")
.add("Pepper")
.remove("Peper")
.add("Onion")
.add("Pepperoni")
.add("Oregano")
.cook();
};
const createSmallPizza = () => {
const pizzaSmall = new Pizza(Pizza.sizes().small);
pizzaSmall
.on("cookFinished", () => {
console.log(`PizzaSmall is ready to release.`);
// no clearing interval of release
})
.on("cookStarted", () => console.log("PizzaSmall is in the oven"))
.on("charredPizza", () =>
console.error("OOPS! The PizzaSmall is charred...")
)
.add("mozzarella")
.add("Meat")
.cook();
};
//createMediumPizza();
createSmallPizza();
@officialabdulrehman
Copy link

On Line 132: you are passing Pizza.slices() which is static method returning 3 values, none of which is small. Is that by mistake or am I missing something ?

@boxgames1
Copy link
Author

@officialabdulrehman line 17 was actually wrong. good catch, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment