From d062e474888b05725d9db35629a2c6edf4a2f7be Mon Sep 17 00:00:00 2001 From: NSnietol Date: Sat, 12 Jan 2019 07:59:54 -0500 Subject: [PATCH] add new patterns --- .../ChainOfResponsibilities/Storage.js | 37 +++++++++++++++++ .../ChainOfResponsibilities/Store.js | 27 +++++++++++++ .../ChainOfResponsibilities/index.js | 9 +++++ .../ChainOfResponsibilities/inventory.json | 29 ++++++++++++++ Node.js-design-patterns/Behaviorals/readme.md | 8 ++++ .../Creationals/Builder/Problem/Person.js | 0 .../Creationals/Builder/Problem/index.js | 0 .../Creationals/Builder/Solution/Person.js | 0 .../Builder/Solution/PersonBuilder.js | 0 .../Creationals/Builder/Solution/index.js | 0 .../Factory Method/Problem/Employee.js | 17 ++++++++ .../Factory Method/Problem/Person.js | 13 ++++++ .../Factory Method/Problem/Shopper.js | 13 ++++++ .../Factory Method/Problem/index.js | 10 +++++ .../Factory Method/Solution/Developer.js | 12 ++++++ .../Factory Method/Solution/Employee.js | 17 ++++++++ .../Factory Method/Solution/Person.js | 13 ++++++ .../Factory Method/Solution/Shopper.js | 13 ++++++ .../Factory Method/Solution/index.js | 9 +++++ .../Factory Method/Solution/userFactory.js | 12 ++++++ .../Creationals/Prototype/Problem/Shopper.js | 26 ++++++++++++ .../Creationals/Prototype/Problem/index.js | 21 ++++++++++ .../Creationals/Prototype/Solution/Shopper.js | 33 +++++++++++++++ .../Creationals/Prototype/Solution/index.js | 12 ++++++ .../Prototype/Solution/scout_prototype.js | 9 +++++ .../Creationals/Singleton/problem/Logger.js | 19 +++++++++ .../Creationals/Singleton/problem/Shopper.js | 15 +++++++ .../Creationals/Singleton/problem/Store.js | 15 +++++++ .../Creationals/Singleton/problem/index.js | 26 ++++++++++++ .../solution/Alternative One/Logger.js | 40 +++++++++++++++++++ .../solution/Alternative One/Shopper.js | 15 +++++++ .../solution/Alternative One/Store.js | 15 +++++++ .../solution/Alternative One/index.js | 26 ++++++++++++ .../solution/Alternative Two/Logger.js | 22 ++++++++++ .../solution/Alternative Two/Shopper.js | 14 +++++++ .../solution/Alternative Two/Store.js | 15 +++++++ .../solution/Alternative Two/index.js | 26 ++++++++++++ Node.js-design-patterns/Creationals/readme.md | 21 ++++++++++ .../Structurals/Adapter/Problem/index.js | 0 .../Structurals/Adapter/Solution/index.js | 0 .../Adapter/Solution/localStorage.js | 0 .../Composite/Solution/CatalogGroup.js | 0 .../Composite/Solution/CatalogItem.js | 0 .../Structurals/Composite/Solution/index.js | 0 .../Structurals/Decorator/InventoryItem.js | 37 +++++++++++++++++ .../Structurals/Decorator/Shopper.js | 29 ++++++++++++++ .../Structurals/Decorator/index.js | 23 +++++++++++ .../Structurals/Proxy/Problem/Readme.md | 0 .../Structurals/Proxy/Problem/Readme.txt | 0 .../Structurals/Proxy/Problem/index.js | 0 .../Structurals/Proxy/Solution/FS_Proxy.js | 0 .../Structurals/Proxy/Solution/Readme.md | 0 .../Structurals/Proxy/Solution/Readme.txt | 0 .../Structurals/Proxy/Solution/index.js | 0 .../Structurals/readme.md | 7 +++- Node.js-design-patterns/readme.md | 33 +++++++++++++++ Node.js.design-patterns/Creationals/readme.md | 4 -- 57 files changed, 737 insertions(+), 5 deletions(-) create mode 100644 Node.js-design-patterns/Behaviorals/ChainOfResponsibilities/Storage.js create mode 100644 Node.js-design-patterns/Behaviorals/ChainOfResponsibilities/Store.js create mode 100644 Node.js-design-patterns/Behaviorals/ChainOfResponsibilities/index.js create mode 100644 Node.js-design-patterns/Behaviorals/ChainOfResponsibilities/inventory.json create mode 100644 Node.js-design-patterns/Behaviorals/readme.md rename {Node.js.design-patterns => Node.js-design-patterns}/Creationals/Builder/Problem/Person.js (100%) rename {Node.js.design-patterns => Node.js-design-patterns}/Creationals/Builder/Problem/index.js (100%) rename {Node.js.design-patterns => Node.js-design-patterns}/Creationals/Builder/Solution/Person.js (100%) rename {Node.js.design-patterns => Node.js-design-patterns}/Creationals/Builder/Solution/PersonBuilder.js (100%) rename {Node.js.design-patterns => Node.js-design-patterns}/Creationals/Builder/Solution/index.js (100%) create mode 100644 Node.js-design-patterns/Creationals/Factory Method/Problem/Employee.js create mode 100644 Node.js-design-patterns/Creationals/Factory Method/Problem/Person.js create mode 100644 Node.js-design-patterns/Creationals/Factory Method/Problem/Shopper.js create mode 100644 Node.js-design-patterns/Creationals/Factory Method/Problem/index.js create mode 100644 Node.js-design-patterns/Creationals/Factory Method/Solution/Developer.js create mode 100644 Node.js-design-patterns/Creationals/Factory Method/Solution/Employee.js create mode 100644 Node.js-design-patterns/Creationals/Factory Method/Solution/Person.js create mode 100644 Node.js-design-patterns/Creationals/Factory Method/Solution/Shopper.js create mode 100644 Node.js-design-patterns/Creationals/Factory Method/Solution/index.js create mode 100644 Node.js-design-patterns/Creationals/Factory Method/Solution/userFactory.js create mode 100644 Node.js-design-patterns/Creationals/Prototype/Problem/Shopper.js create mode 100644 Node.js-design-patterns/Creationals/Prototype/Problem/index.js create mode 100644 Node.js-design-patterns/Creationals/Prototype/Solution/Shopper.js create mode 100644 Node.js-design-patterns/Creationals/Prototype/Solution/index.js create mode 100644 Node.js-design-patterns/Creationals/Prototype/Solution/scout_prototype.js create mode 100644 Node.js-design-patterns/Creationals/Singleton/problem/Logger.js create mode 100644 Node.js-design-patterns/Creationals/Singleton/problem/Shopper.js create mode 100644 Node.js-design-patterns/Creationals/Singleton/problem/Store.js create mode 100644 Node.js-design-patterns/Creationals/Singleton/problem/index.js create mode 100644 Node.js-design-patterns/Creationals/Singleton/solution/Alternative One/Logger.js create mode 100644 Node.js-design-patterns/Creationals/Singleton/solution/Alternative One/Shopper.js create mode 100644 Node.js-design-patterns/Creationals/Singleton/solution/Alternative One/Store.js create mode 100644 Node.js-design-patterns/Creationals/Singleton/solution/Alternative One/index.js create mode 100644 Node.js-design-patterns/Creationals/Singleton/solution/Alternative Two/Logger.js create mode 100644 Node.js-design-patterns/Creationals/Singleton/solution/Alternative Two/Shopper.js create mode 100644 Node.js-design-patterns/Creationals/Singleton/solution/Alternative Two/Store.js create mode 100644 Node.js-design-patterns/Creationals/Singleton/solution/Alternative Two/index.js create mode 100644 Node.js-design-patterns/Creationals/readme.md rename {Node.js.design-patterns => Node.js-design-patterns}/Structurals/Adapter/Problem/index.js (100%) rename {Node.js.design-patterns => Node.js-design-patterns}/Structurals/Adapter/Solution/index.js (100%) rename {Node.js.design-patterns => Node.js-design-patterns}/Structurals/Adapter/Solution/localStorage.js (100%) rename {Node.js.design-patterns => Node.js-design-patterns}/Structurals/Composite/Solution/CatalogGroup.js (100%) rename {Node.js.design-patterns => Node.js-design-patterns}/Structurals/Composite/Solution/CatalogItem.js (100%) rename {Node.js.design-patterns => Node.js-design-patterns}/Structurals/Composite/Solution/index.js (100%) create mode 100644 Node.js-design-patterns/Structurals/Decorator/InventoryItem.js create mode 100644 Node.js-design-patterns/Structurals/Decorator/Shopper.js create mode 100644 Node.js-design-patterns/Structurals/Decorator/index.js rename {Node.js.design-patterns => Node.js-design-patterns}/Structurals/Proxy/Problem/Readme.md (100%) rename {Node.js.design-patterns => Node.js-design-patterns}/Structurals/Proxy/Problem/Readme.txt (100%) rename {Node.js.design-patterns => Node.js-design-patterns}/Structurals/Proxy/Problem/index.js (100%) rename {Node.js.design-patterns => Node.js-design-patterns}/Structurals/Proxy/Solution/FS_Proxy.js (100%) rename {Node.js.design-patterns => Node.js-design-patterns}/Structurals/Proxy/Solution/Readme.md (100%) rename {Node.js.design-patterns => Node.js-design-patterns}/Structurals/Proxy/Solution/Readme.txt (100%) rename {Node.js.design-patterns => Node.js-design-patterns}/Structurals/Proxy/Solution/index.js (100%) rename {Node.js.design-patterns => Node.js-design-patterns}/Structurals/readme.md (65%) create mode 100644 Node.js-design-patterns/readme.md delete mode 100644 Node.js.design-patterns/Creationals/readme.md diff --git a/Node.js-design-patterns/Behaviorals/ChainOfResponsibilities/Storage.js b/Node.js-design-patterns/Behaviorals/ChainOfResponsibilities/Storage.js new file mode 100644 index 0000000..7c999da --- /dev/null +++ b/Node.js-design-patterns/Behaviorals/ChainOfResponsibilities/Storage.js @@ -0,0 +1,37 @@ +class Storage { + + constructor(name, inventory=[], deliveryTime=0) { + this.name = name; + this.inventory = inventory; + this.deliveryTime = deliveryTime; + this.next = null; + } + + lookInLocalInventory(itemName) { + let index = this.inventory.map(item => item.name).indexOf(itemName); + return this.inventory[index]; + } + + setNext(storage) { + this.next = storage; + } + + find(itemName) { + let found = this.lookInLocalInventory(itemName); + if (found) { + return { + name: found.name, + qty: found.qty, + location: this.name, + deliveryTime: (this.deliveryTime === 0) ? 'now' : `${this.deliveryTime} day(s)` + } + } else if (this.next) { + return this.next.find(itemName); + } else { + return `we do not carry ${itemName}`; + } + } + +} + +module.exports = Storage; diff --git a/Node.js-design-patterns/Behaviorals/ChainOfResponsibilities/Store.js b/Node.js-design-patterns/Behaviorals/ChainOfResponsibilities/Store.js new file mode 100644 index 0000000..6319f9d --- /dev/null +++ b/Node.js-design-patterns/Behaviorals/ChainOfResponsibilities/Store.js @@ -0,0 +1,27 @@ +let Storage = require('./Storage'); + +class Store { + + constructor(name, inventory=[]) { + this.name = name; + + let floor = new Storage('store floor', inventory.floor); + let backroom = new Storage('store backroom', inventory.backroom); + let localStore = new Storage('nearby store', inventory.localStore, 1); + let warehouse = new Storage('warehouse', inventory.warehouse, 5); + + floor.setNext(backroom); + backroom.setNext(localStore); + localStore.setNext(warehouse); + + this.storage = floor; + + } + + find(itemName) { + return this.storage.find(itemName); + } + +} + +module.exports = Store; diff --git a/Node.js-design-patterns/Behaviorals/ChainOfResponsibilities/index.js b/Node.js-design-patterns/Behaviorals/ChainOfResponsibilities/index.js new file mode 100644 index 0000000..22ebb9b --- /dev/null +++ b/Node.js-design-patterns/Behaviorals/ChainOfResponsibilities/index.js @@ -0,0 +1,9 @@ +let Store = require('./Store'); +let inventory = require('./inventory'); + +let skiShop = new Store('Steep and Deep', inventory); + +let searchItem = 'powder skis'; +let results = skiShop.find(searchItem); + +console.log( results ); diff --git a/Node.js-design-patterns/Behaviorals/ChainOfResponsibilities/inventory.json b/Node.js-design-patterns/Behaviorals/ChainOfResponsibilities/inventory.json new file mode 100644 index 0000000..21045ff --- /dev/null +++ b/Node.js-design-patterns/Behaviorals/ChainOfResponsibilities/inventory.json @@ -0,0 +1,29 @@ +{ + "floor": [ + { "name": "ski googles", "qty": 5 }, + { "name": "ski hats", "qty": 15 }, + { "name": "all mountain skis", "qty": 2 }, + { "name": "ski boots", "qty": 2 } + ], + "backroom": [ + { "name": "ski googles", "qty": 5 }, + { "name": "ski hats", "qty": 15 }, + { "name": "ski poles", "qty": 2 }, + { "name": "ski rack", "qty": 1 } + ], + "localStore": [ + { "name": "ski boots", "qty": 2 }, + { "name": "ski poles", "qty": 4 }, + { "name": "wax", "qty": 8 } + ], + "warehouse": [ + { "name": "ski googles", "qty": 100 }, + { "name": "ski hats", "qty": 100 }, + { "name": "all mountain skis", "qty": 10 }, + { "name": "ski boots", "qty": 20 }, + { "name": "ski poles", "qty": 20 }, + { "name": "wax", "qty": 100 }, + { "name": "powder skis", "qty": 10 }, + { "name": "ski rack", "qty": 3 } + ] +} diff --git a/Node.js-design-patterns/Behaviorals/readme.md b/Node.js-design-patterns/Behaviorals/readme.md new file mode 100644 index 0000000..45046e5 --- /dev/null +++ b/Node.js-design-patterns/Behaviorals/readme.md @@ -0,0 +1,8 @@ + +## Chain of responsibility + +Intent : "Avoid coupling the sender of a request to its receiver by giving than one object a change to handle the request. Chain the receiving objects and pass the request a long the chain" + +## Command + +Intent : "Encapsulate a request as an object, thereby letting you parameterize with different requests, queue or log requests, and support undoable operations." \ No newline at end of file diff --git a/Node.js.design-patterns/Creationals/Builder/Problem/Person.js b/Node.js-design-patterns/Creationals/Builder/Problem/Person.js similarity index 100% rename from Node.js.design-patterns/Creationals/Builder/Problem/Person.js rename to Node.js-design-patterns/Creationals/Builder/Problem/Person.js diff --git a/Node.js.design-patterns/Creationals/Builder/Problem/index.js b/Node.js-design-patterns/Creationals/Builder/Problem/index.js similarity index 100% rename from Node.js.design-patterns/Creationals/Builder/Problem/index.js rename to Node.js-design-patterns/Creationals/Builder/Problem/index.js diff --git a/Node.js.design-patterns/Creationals/Builder/Solution/Person.js b/Node.js-design-patterns/Creationals/Builder/Solution/Person.js similarity index 100% rename from Node.js.design-patterns/Creationals/Builder/Solution/Person.js rename to Node.js-design-patterns/Creationals/Builder/Solution/Person.js diff --git a/Node.js.design-patterns/Creationals/Builder/Solution/PersonBuilder.js b/Node.js-design-patterns/Creationals/Builder/Solution/PersonBuilder.js similarity index 100% rename from Node.js.design-patterns/Creationals/Builder/Solution/PersonBuilder.js rename to Node.js-design-patterns/Creationals/Builder/Solution/PersonBuilder.js diff --git a/Node.js.design-patterns/Creationals/Builder/Solution/index.js b/Node.js-design-patterns/Creationals/Builder/Solution/index.js similarity index 100% rename from Node.js.design-patterns/Creationals/Builder/Solution/index.js rename to Node.js-design-patterns/Creationals/Builder/Solution/index.js diff --git a/Node.js-design-patterns/Creationals/Factory Method/Problem/Employee.js b/Node.js-design-patterns/Creationals/Factory Method/Problem/Employee.js new file mode 100644 index 0000000..d6fc27f --- /dev/null +++ b/Node.js-design-patterns/Creationals/Factory Method/Problem/Employee.js @@ -0,0 +1,17 @@ +var Shopper = require('./Shopper') + +class Employee extends Shopper { + + constructor(name, money=0, employer='') { + super(name, money); + this.employer = employer; + this.employed = true; + } + + payDay(money=0) { + this.money += money; + } + +} + +module.exports = Employee; diff --git a/Node.js-design-patterns/Creationals/Factory Method/Problem/Person.js b/Node.js-design-patterns/Creationals/Factory Method/Problem/Person.js new file mode 100644 index 0000000..f13d4c0 --- /dev/null +++ b/Node.js-design-patterns/Creationals/Factory Method/Problem/Person.js @@ -0,0 +1,13 @@ +class Person { + + constructor(name='unnamed person') { + this.name = name; + } + + toString() { + return JSON.stringify(this); + } + +} + +module.exports = Person; diff --git a/Node.js-design-patterns/Creationals/Factory Method/Problem/Shopper.js b/Node.js-design-patterns/Creationals/Factory Method/Problem/Shopper.js new file mode 100644 index 0000000..3a4599f --- /dev/null +++ b/Node.js-design-patterns/Creationals/Factory Method/Problem/Shopper.js @@ -0,0 +1,13 @@ +var Person = require('./Person') + +class Shopper extends Person { + + constructor(name, money=0) { + super(name); + this.money = money; + this.employed = false; + } + +} + +module.exports = Shopper; diff --git a/Node.js-design-patterns/Creationals/Factory Method/Problem/index.js b/Node.js-design-patterns/Creationals/Factory Method/Problem/index.js new file mode 100644 index 0000000..f8098f9 --- /dev/null +++ b/Node.js-design-patterns/Creationals/Factory Method/Problem/index.js @@ -0,0 +1,10 @@ +var Shopper = require('./Shopper'); +var Employee = require('./Employee'); + +// El problema recide cuando se se manajan muchos tipos de personas o cuando se requiere +// En tiempo de ejecucion obeter un determinado tipo de persona +var alex = new Shopper('Alex Banks', 100); +var eve = new Employee('Eve Porcello', 100, 'This and That'); + +console.log( alex.toString() ) +console.log( eve.toString() ) diff --git a/Node.js-design-patterns/Creationals/Factory Method/Solution/Developer.js b/Node.js-design-patterns/Creationals/Factory Method/Solution/Developer.js new file mode 100644 index 0000000..0dbcfa3 --- /dev/null +++ b/Node.js-design-patterns/Creationals/Factory Method/Solution/Developer.js @@ -0,0 +1,12 @@ + +var Person = require('./Person') + +class Developer extends Person{ + + constructor(name, money=0,skills) { + super(name); + this.money = money; + this.skills = [...skills]; + } + +} \ No newline at end of file diff --git a/Node.js-design-patterns/Creationals/Factory Method/Solution/Employee.js b/Node.js-design-patterns/Creationals/Factory Method/Solution/Employee.js new file mode 100644 index 0000000..d6fc27f --- /dev/null +++ b/Node.js-design-patterns/Creationals/Factory Method/Solution/Employee.js @@ -0,0 +1,17 @@ +var Shopper = require('./Shopper') + +class Employee extends Shopper { + + constructor(name, money=0, employer='') { + super(name, money); + this.employer = employer; + this.employed = true; + } + + payDay(money=0) { + this.money += money; + } + +} + +module.exports = Employee; diff --git a/Node.js-design-patterns/Creationals/Factory Method/Solution/Person.js b/Node.js-design-patterns/Creationals/Factory Method/Solution/Person.js new file mode 100644 index 0000000..f13d4c0 --- /dev/null +++ b/Node.js-design-patterns/Creationals/Factory Method/Solution/Person.js @@ -0,0 +1,13 @@ +class Person { + + constructor(name='unnamed person') { + this.name = name; + } + + toString() { + return JSON.stringify(this); + } + +} + +module.exports = Person; diff --git a/Node.js-design-patterns/Creationals/Factory Method/Solution/Shopper.js b/Node.js-design-patterns/Creationals/Factory Method/Solution/Shopper.js new file mode 100644 index 0000000..3a4599f --- /dev/null +++ b/Node.js-design-patterns/Creationals/Factory Method/Solution/Shopper.js @@ -0,0 +1,13 @@ +var Person = require('./Person') + +class Shopper extends Person { + + constructor(name, money=0) { + super(name); + this.money = money; + this.employed = false; + } + +} + +module.exports = Shopper; diff --git a/Node.js-design-patterns/Creationals/Factory Method/Solution/index.js b/Node.js-design-patterns/Creationals/Factory Method/Solution/index.js new file mode 100644 index 0000000..f1cedf9 --- /dev/null +++ b/Node.js-design-patterns/Creationals/Factory Method/Solution/index.js @@ -0,0 +1,9 @@ +var userFactory = require('./userFactory'); + +var alex = userFactory('Alex Banks', 100); +var eve = userFactory('Eve Porcello', 100, 'employee', 'This and That'); + +eve.payDay(100); + +console.log( alex.toString() ); +console.log( eve.toString() ); diff --git a/Node.js-design-patterns/Creationals/Factory Method/Solution/userFactory.js b/Node.js-design-patterns/Creationals/Factory Method/Solution/userFactory.js new file mode 100644 index 0000000..95cddbb --- /dev/null +++ b/Node.js-design-patterns/Creationals/Factory Method/Solution/userFactory.js @@ -0,0 +1,12 @@ +var Employee = require('./Employee'); +var Shopper = require('./Shopper'); + +var userFactory = (name, money=0, type, employer) => { + if (type === 'employee') { + return new Employee(name, money, employer); + } else { + return new Shopper(name, money); + } +} + +module.exports = userFactory; diff --git a/Node.js-design-patterns/Creationals/Prototype/Problem/Shopper.js b/Node.js-design-patterns/Creationals/Prototype/Problem/Shopper.js new file mode 100644 index 0000000..bd4ec5b --- /dev/null +++ b/Node.js-design-patterns/Creationals/Prototype/Problem/Shopper.js @@ -0,0 +1,26 @@ +class Shopper { + + constructor(name='unnamed person') { + this._name = name; + this._shoppingList = []; + } + + set name(value) { + this._name = value; + } + + get name() { + return this._name; + } + + get shoppingList() { + return this._shoppingList.join(', '); + } + + addItemToList(item) { + this._shoppingList.push(item); + } + +} + +module.exports = Shopper; diff --git a/Node.js-design-patterns/Creationals/Prototype/Problem/index.js b/Node.js-design-patterns/Creationals/Prototype/Problem/index.js new file mode 100644 index 0000000..0413c15 --- /dev/null +++ b/Node.js-design-patterns/Creationals/Prototype/Problem/index.js @@ -0,0 +1,21 @@ +let Shopper = require('./Shopper'); + +let alex = new Shopper('Alex Banks'); + +// Estos atributos se repiten y las lineas tambien +alex.addItemToList('camping knife'); +alex.addItemToList('tent'); +alex.addItemToList('backpack'); +alex.addItemToList('map'); +//---- +alex.addItemToList('slingshot'); + +let eve = new Shopper('Eve Porcello'); +eve.addItemToList('camping knife'); +eve.addItemToList('tent'); +eve.addItemToList('backpack'); +eve.addItemToList('map'); +eve.addItemToList('reading light'); + +console.log( `${alex.name}: ${alex.shoppingList}` ); +console.log( `${eve.name}: ${eve.shoppingList}` ); diff --git a/Node.js-design-patterns/Creationals/Prototype/Solution/Shopper.js b/Node.js-design-patterns/Creationals/Prototype/Solution/Shopper.js new file mode 100644 index 0000000..5bdd971 --- /dev/null +++ b/Node.js-design-patterns/Creationals/Prototype/Solution/Shopper.js @@ -0,0 +1,33 @@ +class Shopper { + + constructor(name='unnamed person') { + this._name = name; + this._shoppingList = []; + } + + set name(value) { + this._name = value; + } + + get name() { + return this._name; + } + + get shoppingList() { + return this._shoppingList.join(', '); + } + + addItemToList(item) { + this._shoppingList.push(item); + } + clone(){ + let proto = Object.getPrototypeOf(this); + let cloned = Object.create(proto); + cloned._name = this._name; + cloned._shoppingList = [...this._shoppingList]; + return cloned; + + } +} + +module.exports = Shopper; diff --git a/Node.js-design-patterns/Creationals/Prototype/Solution/index.js b/Node.js-design-patterns/Creationals/Prototype/Solution/index.js new file mode 100644 index 0000000..6244eea --- /dev/null +++ b/Node.js-design-patterns/Creationals/Prototype/Solution/index.js @@ -0,0 +1,12 @@ +let scout_prototype = require('./scout_prototype'); + +let alex = scout_prototype.clone(); +alex.name = 'Alex Banks'; +alex.addItemToList('slingshot'); + +let eve = scout_prototype.clone(); +eve.name = 'Eve Porcello'; +eve.addItemToList('reading light'); + +console.log( `${alex.name}: ${alex.shoppingList}` ); +console.log( `${eve.name}: ${eve.shoppingList}` ); diff --git a/Node.js-design-patterns/Creationals/Prototype/Solution/scout_prototype.js b/Node.js-design-patterns/Creationals/Prototype/Solution/scout_prototype.js new file mode 100644 index 0000000..6811825 --- /dev/null +++ b/Node.js-design-patterns/Creationals/Prototype/Solution/scout_prototype.js @@ -0,0 +1,9 @@ +var Shopper = require('./Shopper'); + +var scout = new Shopper(); +scout.addItemToList('camping knife'); +scout.addItemToList('tent'); +scout.addItemToList('backpack'); +scout.addItemToList('map'); + +module.exports = scout; diff --git a/Node.js-design-patterns/Creationals/Singleton/problem/Logger.js b/Node.js-design-patterns/Creationals/Singleton/problem/Logger.js new file mode 100644 index 0000000..ba21a7e --- /dev/null +++ b/Node.js-design-patterns/Creationals/Singleton/problem/Logger.js @@ -0,0 +1,19 @@ +class Logger { + + constructor() { + this.logs = []; + } + + get count() { + return this.logs.length; + } + + log(message) { + const timestamp = new Date().toISOString(); + this.logs.push({ message, timestamp }); + console.log(`${timestamp} - ${message}`); + } + +} + +module.exports = Logger; diff --git a/Node.js-design-patterns/Creationals/Singleton/problem/Shopper.js b/Node.js-design-patterns/Creationals/Singleton/problem/Shopper.js new file mode 100644 index 0000000..b29ac55 --- /dev/null +++ b/Node.js-design-patterns/Creationals/Singleton/problem/Shopper.js @@ -0,0 +1,15 @@ +var Logger = require('./Logger'); + +var logger = new Logger(); + +class Shopper { + + constructor(name, money=0) { + this.name = name; + this.money = money; + logger.log(`New Shopper: ${name} has ${money} in their account.`); + } + +} + +module.exports = Shopper; diff --git a/Node.js-design-patterns/Creationals/Singleton/problem/Store.js b/Node.js-design-patterns/Creationals/Singleton/problem/Store.js new file mode 100644 index 0000000..a358669 --- /dev/null +++ b/Node.js-design-patterns/Creationals/Singleton/problem/Store.js @@ -0,0 +1,15 @@ +var Logger = require('./Logger'); + +var logger = new Logger(); + +class Store { + + constructor(name, inventory=[]) { + this.name = name; + this.inventory = inventory; + logger.log(`New Store: ${name} has ${inventory.length} items in stock.`); + } + +} + +module.exports = Store; diff --git a/Node.js-design-patterns/Creationals/Singleton/problem/index.js b/Node.js-design-patterns/Creationals/Singleton/problem/index.js new file mode 100644 index 0000000..5be564a --- /dev/null +++ b/Node.js-design-patterns/Creationals/Singleton/problem/index.js @@ -0,0 +1,26 @@ +var Logger = require('./Logger'); +var Shopper = require('./Shopper'); +var Store = require('./Store'); + +var logger = new Logger(); + +logger.log('starting app...'); + +var alex = new Shopper('alex', 500) +var ski_shop = new Store('Steep and Deep Supplies', [ + { + item: 'Downhill Skis', + qty: 5, + price: 750 + }, + { + item: 'Knit Hat', + qty: 20, + price: 5 + } +]) + +logger.log('finished config...'); + +console.log(`${logger.count} logs total`); +logger.logs.map(log => console.log(` ${log.message}`)); diff --git a/Node.js-design-patterns/Creationals/Singleton/solution/Alternative One/Logger.js b/Node.js-design-patterns/Creationals/Singleton/solution/Alternative One/Logger.js new file mode 100644 index 0000000..bac158f --- /dev/null +++ b/Node.js-design-patterns/Creationals/Singleton/solution/Alternative One/Logger.js @@ -0,0 +1,40 @@ +class Logger { + + constructor() { + this.logs = []; + } + + get count() { + return this.logs.length; + } + + log(message) { + const timestamp = new Date().toISOString(); + this.logs.push({ message, timestamp }); + console.log(`${timestamp} - ${message}`); + } + +} + + +class Singleton{ + + constructor(){ + if(Singleton.instance){ + Singleton.instance = new Logger(); + } + return Singleton.instance; + } + + static getInstance(){ + if(!Singleton.instance){ + Singleton.instance = new Logger(); + } + return Singleton.instance; + } + + +} + + +module.exports = Singleton; diff --git a/Node.js-design-patterns/Creationals/Singleton/solution/Alternative One/Shopper.js b/Node.js-design-patterns/Creationals/Singleton/solution/Alternative One/Shopper.js new file mode 100644 index 0000000..a371acc --- /dev/null +++ b/Node.js-design-patterns/Creationals/Singleton/solution/Alternative One/Shopper.js @@ -0,0 +1,15 @@ +var Logger = require('./Logger'); + +var logger = Logger.getInstance(); + +class Shopper { + + constructor(name, money=0) { + this.name = name; + this.money = money; + logger.log(`New Shopper: ${name} has ${money} in their account.`); + } + +} + +module.exports = Shopper; diff --git a/Node.js-design-patterns/Creationals/Singleton/solution/Alternative One/Store.js b/Node.js-design-patterns/Creationals/Singleton/solution/Alternative One/Store.js new file mode 100644 index 0000000..7af6aec --- /dev/null +++ b/Node.js-design-patterns/Creationals/Singleton/solution/Alternative One/Store.js @@ -0,0 +1,15 @@ +var Logger = require('./Logger'); + +var logger = Logger.getInstance(); + +class Store { + + constructor(name, inventory=[]) { + this.name = name; + this.inventory = inventory; + logger.log(`New Store: ${name} has ${inventory.length} items in stock.`); + } + +} + +module.exports = Store; diff --git a/Node.js-design-patterns/Creationals/Singleton/solution/Alternative One/index.js b/Node.js-design-patterns/Creationals/Singleton/solution/Alternative One/index.js new file mode 100644 index 0000000..8812e28 --- /dev/null +++ b/Node.js-design-patterns/Creationals/Singleton/solution/Alternative One/index.js @@ -0,0 +1,26 @@ +var Logger = require('./Logger'); +var Shopper = require('./Shopper'); +var Store = require('./Store'); + +var logger = Logger.getInstance(); + +logger.log('starting app...'); + +var alex = new Shopper('alex', 500) +var ski_shop = new Store('Steep and Deep Supplies', [ + { + item: 'Downhill Skis', + qty: 5, + price: 750 + }, + { + item: 'Knit Hat', + qty: 20, + price: 5 + } +]) + +logger.log('finished config...'); + +console.log(`${logger.count} logs total`); +logger.logs.map(log => console.log(` ${log.message}`)); diff --git a/Node.js-design-patterns/Creationals/Singleton/solution/Alternative Two/Logger.js b/Node.js-design-patterns/Creationals/Singleton/solution/Alternative Two/Logger.js new file mode 100644 index 0000000..3e159e0 --- /dev/null +++ b/Node.js-design-patterns/Creationals/Singleton/solution/Alternative Two/Logger.js @@ -0,0 +1,22 @@ +class Logger { + + constructor() { + this.logs = []; + } + + get count() { + return this.logs.length; + } + + log(message) { + const timestamp = new Date().toISOString(); + this.logs.push({ message, timestamp }); + console.log(`${timestamp} - ${message}`); + } + +} + + +// Se exporta una unica instancia de la clase Logger +// Lo que permite que se utilice solo esta durante la ejecucion del programa +module.exports = new Logger(); diff --git a/Node.js-design-patterns/Creationals/Singleton/solution/Alternative Two/Shopper.js b/Node.js-design-patterns/Creationals/Singleton/solution/Alternative Two/Shopper.js new file mode 100644 index 0000000..3ee2f51 --- /dev/null +++ b/Node.js-design-patterns/Creationals/Singleton/solution/Alternative Two/Shopper.js @@ -0,0 +1,14 @@ +var logger = require('./Logger'); + + +class Shopper { + + constructor(name, money=0) { + this.name = name; + this.money = money; + logger.log(`New Shopper: ${name} has ${money} in their account.`); + } + +} + +module.exports = Shopper; diff --git a/Node.js-design-patterns/Creationals/Singleton/solution/Alternative Two/Store.js b/Node.js-design-patterns/Creationals/Singleton/solution/Alternative Two/Store.js new file mode 100644 index 0000000..5ff6b89 --- /dev/null +++ b/Node.js-design-patterns/Creationals/Singleton/solution/Alternative Two/Store.js @@ -0,0 +1,15 @@ +var logger = require('./Logger'); + + + +class Store { + + constructor(name, inventory=[]) { + this.name = name; + this.inventory = inventory; + logger.log(`New Store: ${name} has ${inventory.length} items in stock.`); + } + +} + +module.exports = Store; diff --git a/Node.js-design-patterns/Creationals/Singleton/solution/Alternative Two/index.js b/Node.js-design-patterns/Creationals/Singleton/solution/Alternative Two/index.js new file mode 100644 index 0000000..e78c351 --- /dev/null +++ b/Node.js-design-patterns/Creationals/Singleton/solution/Alternative Two/index.js @@ -0,0 +1,26 @@ +var logger = require('./Logger'); +var Shopper = require('./Shopper'); +var Store = require('./Store'); + + + +logger.log('starting app...'); + +var alex = new Shopper('alex', 500) +var ski_shop = new Store('Steep and Deep Supplies', [ + { + item: 'Downhill Skis', + qty: 5, + price: 750 + }, + { + item: 'Knit Hat', + qty: 20, + price: 5 + } +]) + +logger.log('finished config...'); + +console.log(`${logger.count} logs total`); +logger.logs.map(log => console.log(` ${log.message}`)); diff --git a/Node.js-design-patterns/Creationals/readme.md b/Node.js-design-patterns/Creationals/readme.md new file mode 100644 index 0000000..d1bfc1f --- /dev/null +++ b/Node.js-design-patterns/Creationals/readme.md @@ -0,0 +1,21 @@ + +## Singleton + + +Intent "Ensure a class only has one instance, and provide a global point of access to it" + + +## Prototype + +Intent "Specify the kinds of objects to create using prototypicla instace, and create new objects by copying this prototype" + + +## Factory Method + +Intent "Define an interface for creating an object but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses". + + +## Builder + +Intent: "Separate the construction of a complex object from its representation so that the same construciton process can creat different representations." + diff --git a/Node.js.design-patterns/Structurals/Adapter/Problem/index.js b/Node.js-design-patterns/Structurals/Adapter/Problem/index.js similarity index 100% rename from Node.js.design-patterns/Structurals/Adapter/Problem/index.js rename to Node.js-design-patterns/Structurals/Adapter/Problem/index.js diff --git a/Node.js.design-patterns/Structurals/Adapter/Solution/index.js b/Node.js-design-patterns/Structurals/Adapter/Solution/index.js similarity index 100% rename from Node.js.design-patterns/Structurals/Adapter/Solution/index.js rename to Node.js-design-patterns/Structurals/Adapter/Solution/index.js diff --git a/Node.js.design-patterns/Structurals/Adapter/Solution/localStorage.js b/Node.js-design-patterns/Structurals/Adapter/Solution/localStorage.js similarity index 100% rename from Node.js.design-patterns/Structurals/Adapter/Solution/localStorage.js rename to Node.js-design-patterns/Structurals/Adapter/Solution/localStorage.js diff --git a/Node.js.design-patterns/Structurals/Composite/Solution/CatalogGroup.js b/Node.js-design-patterns/Structurals/Composite/Solution/CatalogGroup.js similarity index 100% rename from Node.js.design-patterns/Structurals/Composite/Solution/CatalogGroup.js rename to Node.js-design-patterns/Structurals/Composite/Solution/CatalogGroup.js diff --git a/Node.js.design-patterns/Structurals/Composite/Solution/CatalogItem.js b/Node.js-design-patterns/Structurals/Composite/Solution/CatalogItem.js similarity index 100% rename from Node.js.design-patterns/Structurals/Composite/Solution/CatalogItem.js rename to Node.js-design-patterns/Structurals/Composite/Solution/CatalogItem.js diff --git a/Node.js.design-patterns/Structurals/Composite/Solution/index.js b/Node.js-design-patterns/Structurals/Composite/Solution/index.js similarity index 100% rename from Node.js.design-patterns/Structurals/Composite/Solution/index.js rename to Node.js-design-patterns/Structurals/Composite/Solution/index.js diff --git a/Node.js-design-patterns/Structurals/Decorator/InventoryItem.js b/Node.js-design-patterns/Structurals/Decorator/InventoryItem.js new file mode 100644 index 0000000..1bd4d0e --- /dev/null +++ b/Node.js-design-patterns/Structurals/Decorator/InventoryItem.js @@ -0,0 +1,37 @@ +class InventoryItem { + + constructor(name, price) { + this.name = name + this.price = price + } + + print() { + console.log(`${item.name} costs ${item.price}`) + } + +} + +class GoldenInventoryItem { + + constructor(baseItem) { + this.name = `Golden ${baseItem.name}`; + this.price = 1000 + baseItem.price; + } + +} + +class DiamondInventoryItem { + + constructor(baseItem) { + this.name = `Diamond ${baseItem.name}`; + this.price = 1000 + baseItem.price; + this.cutsGlass = true; + } + + print() { + console.log(`${this.name} costs a lot of money...`); + } + +} + +module.exports = {InventoryItem, GoldenInventoryItem, DiamondInventoryItem}; diff --git a/Node.js-design-patterns/Structurals/Decorator/Shopper.js b/Node.js-design-patterns/Structurals/Decorator/Shopper.js new file mode 100644 index 0000000..258a79d --- /dev/null +++ b/Node.js-design-patterns/Structurals/Decorator/Shopper.js @@ -0,0 +1,29 @@ +class Shopper { + + constructor(name, account=0) { + this.name = name; + this.account = account; + this.items = []; + } + + purchase(item) { + if (item.price > this.account) { + console.log(`Cannot afford ${item.name}`); + } else { + console.log(`Purchasing item ${item.name}`); + this.account -= item.price; + this.items.push(item); + } + } + + printStatus() { + console.log(`${this.name} has purchased ${this.items.length} items:`); + this.items.forEach(item => { + console.log(` * ${item.name} - ${item.price}`); + }) + console.log(`${this.name} has $${this.account.toFixed(2)} remaining.`); + } + +} + +module.exports = Shopper; diff --git a/Node.js-design-patterns/Structurals/Decorator/index.js b/Node.js-design-patterns/Structurals/Decorator/index.js new file mode 100644 index 0000000..4def3b5 --- /dev/null +++ b/Node.js-design-patterns/Structurals/Decorator/index.js @@ -0,0 +1,23 @@ +let Shopper = require('./Shopper'); +let { + InventoryItem, + GoldenInventoryItem, + DiamondInventoryItem +} = require('./InventoryItem'); + +let alex = new Shopper('Alex', 3500); + +let walkman = new InventoryItem("Walkman", 29.99); +let necklace = new InventoryItem("Necklace", 9.99); + +let gold_necklace = new GoldenInventoryItem(necklace); +let diamond_gold_necklace = new DiamondInventoryItem(gold_necklace); + +let diamond_walkman = new DiamondInventoryItem(walkman); + +alex.purchase(diamond_gold_necklace); +alex.purchase(diamond_walkman); + +alex.printStatus(); + +diamond_walkman.print(); diff --git a/Node.js.design-patterns/Structurals/Proxy/Problem/Readme.md b/Node.js-design-patterns/Structurals/Proxy/Problem/Readme.md similarity index 100% rename from Node.js.design-patterns/Structurals/Proxy/Problem/Readme.md rename to Node.js-design-patterns/Structurals/Proxy/Problem/Readme.md diff --git a/Node.js.design-patterns/Structurals/Proxy/Problem/Readme.txt b/Node.js-design-patterns/Structurals/Proxy/Problem/Readme.txt similarity index 100% rename from Node.js.design-patterns/Structurals/Proxy/Problem/Readme.txt rename to Node.js-design-patterns/Structurals/Proxy/Problem/Readme.txt diff --git a/Node.js.design-patterns/Structurals/Proxy/Problem/index.js b/Node.js-design-patterns/Structurals/Proxy/Problem/index.js similarity index 100% rename from Node.js.design-patterns/Structurals/Proxy/Problem/index.js rename to Node.js-design-patterns/Structurals/Proxy/Problem/index.js diff --git a/Node.js.design-patterns/Structurals/Proxy/Solution/FS_Proxy.js b/Node.js-design-patterns/Structurals/Proxy/Solution/FS_Proxy.js similarity index 100% rename from Node.js.design-patterns/Structurals/Proxy/Solution/FS_Proxy.js rename to Node.js-design-patterns/Structurals/Proxy/Solution/FS_Proxy.js diff --git a/Node.js.design-patterns/Structurals/Proxy/Solution/Readme.md b/Node.js-design-patterns/Structurals/Proxy/Solution/Readme.md similarity index 100% rename from Node.js.design-patterns/Structurals/Proxy/Solution/Readme.md rename to Node.js-design-patterns/Structurals/Proxy/Solution/Readme.md diff --git a/Node.js.design-patterns/Structurals/Proxy/Solution/Readme.txt b/Node.js-design-patterns/Structurals/Proxy/Solution/Readme.txt similarity index 100% rename from Node.js.design-patterns/Structurals/Proxy/Solution/Readme.txt rename to Node.js-design-patterns/Structurals/Proxy/Solution/Readme.txt diff --git a/Node.js.design-patterns/Structurals/Proxy/Solution/index.js b/Node.js-design-patterns/Structurals/Proxy/Solution/index.js similarity index 100% rename from Node.js.design-patterns/Structurals/Proxy/Solution/index.js rename to Node.js-design-patterns/Structurals/Proxy/Solution/index.js diff --git a/Node.js.design-patterns/Structurals/readme.md b/Node.js-design-patterns/Structurals/readme.md similarity index 65% rename from Node.js.design-patterns/Structurals/readme.md rename to Node.js-design-patterns/Structurals/readme.md index 1bc7348..d30b9f5 100644 --- a/Node.js.design-patterns/Structurals/readme.md +++ b/Node.js-design-patterns/Structurals/readme.md @@ -7,4 +7,9 @@ Intent : "Provide a surrogate of placeholder for another object to control acces ## Composite -Intent : "Composite objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly." \ No newline at end of file +Intent : "Composite objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly." + +## Decorator + +Intent : "Attach additional responsabilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality" + diff --git a/Node.js-design-patterns/readme.md b/Node.js-design-patterns/readme.md new file mode 100644 index 0000000..e1bc2e8 --- /dev/null +++ b/Node.js-design-patterns/readme.md @@ -0,0 +1,33 @@ +# Desing Patterns + +"Each pattern describes a problem which occurs over and over again in our environmentm and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice" Christopher Alexander + +Cataloged solutions + +Reusable in many different situations + +Well documented + +Language for collaboration + +Improve architecture + + +Design Pattern Essentials + +Pattern name +The Problem +The Solution +Consequences + + +Anti-Patterns + +* Modifying the prototype on an instance + person.__proto__.address={} + + +* Syncing execution after initialization + + +* Callback Hell \ No newline at end of file diff --git a/Node.js.design-patterns/Creationals/readme.md b/Node.js.design-patterns/Creationals/readme.md deleted file mode 100644 index 921f972..0000000 --- a/Node.js.design-patterns/Creationals/readme.md +++ /dev/null @@ -1,4 +0,0 @@ -## Builder - -Intent: "Separate the construction of a complex object from its representation so that the same construciton process can creat different representations." -