Created
October 13, 2015 16:38
-
-
Save OriginUnknown/7feab8793819b7358582 to your computer and use it in GitHub Desktop.
JavaScript OOP Design Patterns - Decorator Pattern
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Decorator pattern | |
var Starbucks = (function () { | |
var api = {}; | |
//Base function for creating beverages and condiments | |
function Create ( product ) { | |
function Product () { | |
this._description = product || ""; | |
this._cost = 0.00; | |
} | |
//Base methods required for all descendents | |
Product.prototype = { | |
"setCost": function ( cost ) { | |
this._cost = cost; | |
return this; | |
}, | |
"getCost": function () { | |
return this._cost; | |
}, | |
"setDescription": function ( desc ) { | |
this._description = desc; | |
return this; | |
}, | |
"getDescription": function () { | |
return this._description; | |
} | |
}; | |
return new Product(); | |
} | |
/**Starbucks menu**/ | |
/**Beverages - these are the object to decorate**/ | |
var Latte = Create( "Latte" ).setCost( 1.50 ), | |
Cappuccino = Create( "Cappuccino" ).setCost( 1.70 ), | |
Mocha = Create( "Mocha" ).setCost( 1.60 ), | |
Macchiato = Create( "Macchiato" ).setCost( 1.65 ), | |
Tea = Create( "Tea" ).setCost( 1.20 ); | |
/**Condiments - these are the objects that beverages will be decorated with**/ | |
var Soya = Create( "Soya" ).setCost( 0.85 ), | |
Milk = Create( "Milk" ).setCost( 0.65 ), | |
AlmondMilk = Create( "Almond milk" ).setCost( 0.95 ), | |
ChocolateSprinkles = Create( "Chocolate sprinkles" ).setCost( 0.15 ), | |
Marshmellows = Create( "Mini marshmellows" ).setCost( 0.85 ), | |
CinnamonSprinkles = Create( "Cinnamon sprinkles" ).setCost( 0.20 ), | |
Sugar = Create( "Sugar" ).setCost( 0.35 ); | |
/**Cup Sizes*/ | |
var Small = Create( "Small" ).setCost( 0.69 ), | |
Medium = Create( "Regular" ).setCost( 0.79 ), | |
Large = Create( "Grande" ).setCost( 0.99 ); | |
/**Starbucks cashiers - behaviours**/ | |
var Cashier = function () { | |
var cashier = {}, requestArray = [], customerRequestStr = "", | |
customerRequest = [];//[SmallObj, MochaObj, SoyaObj, ...] | |
/**private methods for the cashier to use*/ | |
function resetRequest () { | |
customerRequest = []; | |
customerRequestStr = ""; | |
} | |
function getProduct ( product, index, req ) { | |
switch ( product ) { | |
case "Small": | |
customerRequest.push( Small ); | |
break; | |
case "Regular": | |
customerRequest.push( Medium ); | |
break; | |
case "Grande": | |
customerRequest.push( Large ); | |
break; | |
case "Latte": | |
customerRequest.push( Latte ); | |
break; | |
case "Cappuccino": | |
customerRequest.push( Cappuccino ); | |
break; | |
case "Mocha": | |
customerRequest.push( Mocha ); | |
break; | |
case "Macchiato": | |
customerRequest.push( Macchiato ); | |
break; | |
case "Tea": | |
customerRequest.push( Tea ); | |
break; | |
case "Soya": | |
customerRequest.push( Soya ); | |
break; | |
case "Milk": | |
customerRequest.push( Milk ); | |
break; | |
case "Almond milk": | |
customerRequest.push( AlmondMilk ); | |
break; | |
case "Chocolate sprinkles": | |
customerRequest.push( ChocolateSprinkles ); | |
break; | |
case "Mini marshmellows": | |
customerRequest.push( Marshmellows ); | |
break; | |
case "Cinnamon sprinkles": | |
customerRequest.push( CinnamonSprinkles ); | |
break; | |
case "Sugar": | |
customerRequest.push( Sugar ); | |
break; | |
} | |
} | |
function getCustomerRequest ( item, index, custArr ) { | |
customerRequestStr += item.getDescription() + " "; | |
} | |
cashier.takeOrder = function ( req ) {//req -> ["Grande", "Mocha", ...] | |
var requestArray = req; | |
requestArray.forEach( getProduct ); | |
customerRequest.forEach( getCustomerRequest ); | |
return customerRequestStr.trim(); | |
}; | |
cashier.total = function () { | |
var total = 0; | |
function totalProducts ( product, index, arr ) { | |
total += product.getCost(); | |
} | |
customerRequest.forEach( totalProducts ); | |
/**Reset for next customer order**/ | |
resetRequest(); | |
return total; | |
}; | |
return cashier; | |
}; | |
/**Common behaviour of a Starbucks' customer*/ | |
var Customer = function () { | |
function Customer () { | |
this._customerRequest = []; | |
} | |
Customer.prototype = { | |
"getRequest": function ( req ) { | |
return this._customerRequest; | |
}, | |
"request": function ( req ) { | |
this._customerRequest = req; | |
return this; | |
} | |
}; | |
return new Customer(); | |
}; | |
api.cashier = Cashier; | |
api.customer = Customer; | |
return api; | |
})(); | |
//Starbucks employees - Mike and Marie | |
var MikeCashier = Starbucks.cashier(), | |
MarieCashier = Starbucks.cashier(); | |
//Starbucks customers - Joey, Anna and Ru | |
var Joey = Starbucks.customer(), | |
Anna = Starbucks.customer(), | |
Ru = Starbucks.customer(); | |
Joey.request( [ "Small", "Mocha" ] ); | |
Anna.request( [ "Regular", "Cappuccino" ] ); | |
Ru.request( [ "Grande", "Mocha", "Milk", "Sugar" ] ); | |
//Mike and Marie take Joey, Anna and Ru's request and tell them their total | |
console.log( MikeCashier.takeOrder( Joey.getRequest() ) ); | |
console.log( MikeCashier.total() ); | |
console.log( MarieCashier.takeOrder( Anna.getRequest() ) ); | |
console.log( MarieCashier.total() ); | |
console.log( MikeCashier.takeOrder( Ru.getRequest() ) ); | |
console.log( MikeCashier.total() ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment