Last active
December 12, 2016 23:47
-
-
Save duncanjbrown/5ff1d2f5c217fdb8a2e015379427b520 to your computer and use it in GitHub Desktop.
Decoration with mixins in ES6
This file contains hidden or 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
// The object to be decorated | |
class Coffee { | |
price() { | |
return 10; | |
} | |
notify(message) { | |
console.log('coffee got a message: ' + message); | |
} | |
} | |
// Another object | |
class WithCream { | |
price() { | |
return 5; | |
} | |
notify(message) { | |
console.log('withcream got a message: ' + message); | |
} | |
} | |
// The way the decoration is done | |
const CoffeeDecorator = { | |
decorate(original) { | |
const decorated = Object.create(original); | |
decorated.price = () => { | |
return this.price() + original.price(); | |
} | |
decorated.notify = (message) => { | |
this.notify(message); | |
original.notify(message); | |
} | |
return decorated; | |
} | |
} | |
// The granting of the decorator role | |
Object.assign(WithCream.prototype, CoffeeDecorator); | |
// An object that will play a role | |
class Barista { | |
closeShop() { | |
this.notifySubscribers('Shop is shutting'); | |
} | |
} | |
// The way observing is done | |
const Observable = { | |
subscribers() { | |
return this._subscribers || (this._subscribers = []); | |
}, | |
addSubscriber(subscriber) { | |
return this.subscribers().push(subscriber); | |
}, | |
notifySubscribers(event){ | |
return this.subscribers().map((s) => s.notify(event)); | |
} | |
}; | |
// The granting of the Observer role | |
Object.assign(Barista.prototype, Observable); | |
// do some decorating | |
const original = new Coffee; | |
const dec = new WithCream; | |
const decorated = dec.decorate(original); | |
// see the prices are added per specified decorator logic | |
console.log(original.price()); | |
console.log(decorated.price()); | |
// make an observable and observe it | |
const barista = new Barista; | |
barista.addSubscriber(decorated); | |
// see that each thing is notified per specified notification logic | |
barista.closeShop(); | |
// dynamically add a property | |
// no inheritance! | |
Object.assign(Coffee.prototype, Observable); | |
const customer = { | |
notify(event) { | |
console.log('Customer got a message: ' + event); | |
} | |
} | |
const noisyCoffee = new Coffee; | |
noisyCoffee.addSubscriber(customer); | |
noisyCoffee.notifySubscribers('Caution HOT!') | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment