-
-
Save Whistler092/7875141e89a2cefb8326984776a9a5fd to your computer and use it in GitHub Desktop.
Ejemplos de código para el curso de patrones de diseño para UNIAJC
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
'use strict'; | |
class HotDrink { | |
consume() { | |
/* abstract */ | |
} | |
} | |
class Tea extends HotDrink { | |
consume() { | |
console.log(`Este té es rico con limón!`); | |
} | |
} | |
class Coffee extends HotDrink { | |
consume() { | |
console.log(`Este café es delicioso!`); | |
} | |
} | |
class HotDrinkFactory { | |
prepare(amount) { | |
/* abstract */ | |
} | |
} | |
// Construyendo los factories para el Tea y el Coffee | |
class TeaFactory extends HotDrinkFactory { | |
prepare(amount) { | |
console.log(`Pon en la bolsa de té, hervir agua, verter ${amount}ml`); | |
return new Tea(); // Se retorna el objeto con fines de personalización. | |
} | |
} | |
class CoffeeFactory extends HotDrinkFactory { | |
prepare(amount) { | |
console.log(`Muele algunos granos, hervir agua, verter ${amount}ml`); | |
return new Coffee(); // Se retorna el objeto para personalización. | |
} | |
} | |
/* | |
// NOTA: Versión sin Abstract Factory | |
class HotDrinkMachine { | |
makeDrink(type) { | |
switch (type) { | |
case "tea": | |
return new TeaFactory().prepare(200); | |
case "coffee": | |
return new CoffeeFactory().prepare(50); | |
default: | |
throw new Error(""); | |
} | |
} | |
} | |
let machine = new HotDrinkMachine(); | |
let drink = machine.makeDrink("tea"); | |
drink.consume(); | |
*/ | |
let AvailableDrink = Object.freeze({ | |
coffee: CoffeeFactory, | |
tea: TeaFactory, | |
}); | |
class HotDrinkMachine { | |
constructor() { | |
this.factories = {}; | |
// Instanciamos todas las factories | |
for (let drink in AvailableDrink) { | |
this.factories[drink] = new AvailableDrink[drink](); | |
} | |
} | |
makeDrink(type, amount) { | |
console.log(`Ingresando parametros para preparar ${type}, en ${amount}ml`); | |
return this.factories[type].prepare(amount); //Retorna Objeto Tea o Coffee | |
} | |
} | |
// Ahora para poder usar la maquina correctamente. | |
let machine = new HotDrinkMachine(); | |
// TÉ | |
let drinkTea = machine.makeDrink("tea", 200); | |
drinkTea.consume(); | |
// CAFÉ | |
let drinkCoffee = machine.makeDrink("coffee", 50); | |
drinkCoffee.consume(); | |
// Ingresando parametros para preparar tea, en 200ml | |
// Pon en la bolsa de té, hervir agua, verter 200ml | |
// Este té es rico con limón! | |
// Ingresando parametros para preparar coffee, en 50ml | |
// Muele algunos granos, hervir agua, verter 50ml | |
// Este café es delicioso! |
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
class House { | |
/* Espacio para el objeto casa */ | |
constructor() { | |
this.walls = this.floor = this.floor = `Sin definir`; | |
this.doors = 0; | |
} | |
} | |
class HouseBuilder { | |
constructor(house = new House()) { | |
this.house = house; | |
} | |
walls(walls) { | |
this.house.walls = walls; | |
return this; // Fluent Interface | |
} | |
floor(floor) { | |
this.house.floor = floor; | |
return this; // Fluent Interface | |
} | |
roof(roof) { | |
this.house.roof = roof; | |
return this; // Fluent Interface | |
} | |
doors(doors) { | |
this.house.doors = doors; | |
return this; // Fluent Interface | |
} | |
garage(garage) { | |
this.house.garage = garage; | |
return this; // Fluent Interface | |
} | |
swimmingPool(swimmingPool) { | |
this.house.swimmingPool = swimmingPool; | |
return this; | |
} | |
garden(garden) { | |
this.house.garden = garden; | |
return this; | |
} | |
build() { | |
return this.house; | |
} | |
} | |
let houseBuilder = new HouseBuilder(); | |
let house = houseBuilder | |
.floor("piso de marmol") | |
.roof("techo en plancha") | |
.doors(3) | |
.garage("con garaje doble") | |
.swimmingPool("Con piscina de 30x30") | |
.build(); | |
console.log(house); | |
/* | |
House { | |
floor: 'piso de marmol', | |
walls: 'Sin definir', | |
doors: 3, | |
roof: 'techo en plancha', | |
garage: 'con garaje doble', | |
swimmingPool: 'Con piscina de 30x30' | |
} | |
*/ |
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
'use strict'; | |
class Builder | |
{ | |
buildPart() { /* abstract */ } | |
buildWalls() { /* abstract */ } | |
buildFloor() { /* abstract */ } | |
buildRoof() { /* abstract */ } | |
buildDoors() { /* abstract */ } | |
} | |
class House | |
{ | |
/* Espacio para el objeto casa */ | |
constructor(){ | |
this.walls = `Sin definir`; | |
this.floor = `Sin definir`; | |
this.floor = `Sin definir`; | |
this.doors = 0; | |
} | |
} | |
class HouseWithGarageBuilders extends Builder | |
{ | |
constructor() | |
{ | |
super(); | |
} | |
buildPart() | |
{ | |
this.house = new House(); | |
this.buildWalls(); | |
this.buildFloor(); | |
this.buildRoof(); | |
this.buildDoors(); | |
// Paso en especifico para la implementación | |
this.buildGarage(); | |
} | |
buildWalls() { | |
this.house.walls = `paredes blancas`; | |
} | |
buildFloor() { | |
this.house.floor = `piso de madera`; | |
} | |
buildRoof() { | |
this.house.floor = `techo en flecha`; | |
} | |
buildDoors() { | |
this.house.doors = 2; | |
} | |
buildGarage(){ | |
this.house.garage = `con garaje`; | |
} | |
getResults() | |
{ | |
return this.house; | |
} | |
} | |
class HouseLuxuryBuilders extends Builder | |
{ | |
constructor() | |
{ | |
super(); | |
} | |
buildPart() | |
{ | |
this.house = new House(); | |
this.buildWalls(); | |
this.buildFloor(); | |
this.buildRoof(); | |
this.buildDoors(); | |
// Paso en especifico para la implementación | |
this.buildGarage(); | |
this.buildSwimmingPool(); | |
this.buildGarden(); | |
} | |
buildWalls() { | |
this.house.walls = `paredes blancas en veneciano`; | |
} | |
buildFloor() { | |
this.house.floor = `piso de marmol`; | |
} | |
buildRoof() { | |
this.house.floor = `techo en flecha con atico`; | |
} | |
buildDoors() { | |
this.house.doors = 4; | |
} | |
buildGarage(){ | |
this.house.garage = `con garaje doble`; | |
} | |
buildSwimmingPool(){ | |
this.house.swimmingPool = `con piscina`; | |
} | |
buildGarden(){ | |
this.house.garden = `con jardin`; | |
} | |
getResults() | |
{ | |
return this.house; | |
} | |
} | |
class Director | |
{ | |
construct(builder) | |
{ | |
console.log(`Orquestando las operaciones de construcción`); | |
builder.buildPart(); | |
return builder.getResults(); | |
} | |
} | |
// Use the Builder | |
let luxHouse = new HouseLuxuryBuilders(); | |
let withGarageHouse = new HouseWithGarageBuilders(); | |
let director = new Director(); | |
let newLuxHouse = director.construct(luxHouse); | |
// Orquestando las operaciones de construcción | |
let newWithGarageHouse = director.construct(withGarageHouse); | |
// Orquestando las operaciones de construcción | |
console.log(`Casa Lujosa:: ${JSON.stringify(newLuxHouse)}`); | |
/* | |
Casa Lujosa:: | |
{ | |
"walls": "paredes blancas en veneciano", | |
"floor": "techo en flecha con atico", | |
"doors": 4, | |
"garage": "con garaje doble", | |
"swimmingPool": "con piscina", | |
"garden": "con jardin" | |
} | |
*/ | |
console.log(`Casa con Garaje:: ${JSON.stringify(newWithGarageHouse)}`); | |
/* | |
Casa con Garaje:: | |
{ | |
"walls": "paredes blancas", | |
"floor": "techo en flecha", | |
"doors": 2, | |
"garage": "con garaje" | |
} | |
*/ |
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
'use strict'; | |
class LogisticalPackage { | |
Operation() { | |
/* abstract */ | |
} | |
Add(Component) { | |
/* abstract */ | |
} | |
Remove(Component) { | |
/* abstract */ | |
} | |
GetChild(key) { | |
/* abstract */ | |
} | |
} | |
class BoxContainer extends LogisticalPackage { | |
constructor(name) { | |
super(); | |
this.name = name; | |
this.children = []; | |
console.log(`Creada un nuevo BoxContainer: ${this.name}`); | |
} | |
Operation() { | |
console.log("Ejecutando las operaciones de BoxContainer: " + this.name); | |
for (var i in this.children) this.children[i].Operation(); | |
} | |
Add(Component) { | |
this.children.push(Component); | |
} | |
Remove(Component) { | |
for (var i in this.children) | |
if (this.children[i] === Component) this.children.splice(i, 1); | |
} | |
GetChild(key) { | |
let child = this.children[key]; | |
console.log(`${this.name}: Obteniendo hijos ${child}`); | |
return child; | |
} | |
} | |
class Item extends LogisticalPackage { | |
constructor(name, price) { | |
super(); | |
this.name = name; | |
this.price = price; | |
console.log(`Creado nuevo articulo ${this.name} $${this.price}`); | |
} | |
Operation() { | |
console.log( | |
`Ejecutando Operación para el Item: ${this.name} $${this.price}` | |
); | |
return this.price; | |
} | |
} | |
let caja1 = new BoxContainer("Caja de Celular"); | |
// Creada un nuevo BoxContainer: Caja de Celular | |
caja1.Add(new Item("Celular", 800)); | |
// Creado nuevo articulo Celular $800 | |
caja1.Add(new Item("Audifonos", 100)); | |
// Creado nuevo articulo Audifonos $100 | |
let caja2 = new BoxContainer("Caja de Accesorios"); | |
// Creada un nuevo BoxContainer: Caja de Accesorios | |
caja2.Add(new Item("Cargador Celular", 80)); | |
// Creado nuevo articulo Cargador Celular $80 | |
caja2.Add(new Item("Powerbank", 200)); | |
// Creado nuevo articulo Powerbank $200 | |
let cajaPrincipal = new BoxContainer("Envio #12345"); | |
// Creada un nuevo BoxContainer: Envio #12345 | |
cajaPrincipal.Add(caja1); | |
cajaPrincipal.Add(caja2); | |
cajaPrincipal.Operation(); | |
/* | |
Ejecutando las operaciones de BoxContainer: Envio #12345 | |
Ejecutando las operaciones de BoxContainer: Caja de Celular | |
Ejecutando Operación para el Item: Celular $800 | |
Ejecutando Operación para el Item: Audifonos $100 | |
Ejecutando las operaciones de BoxContainer: Caja de Accesorios | |
Ejecutando Operación para el Item: Cargador Celular $80 | |
Ejecutando Operación para el Item: Powerbank $200 | |
*/ |
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
"use strict"; | |
class Shape { | |
/* abstract */ | |
} | |
class Circle extends Shape { | |
constructor(radius = 0) { | |
super(); | |
this.radius = radius; | |
} | |
resize(factor) { | |
this.radius *= factor; | |
} | |
toString() { | |
return `Un circulo de radio ${this.radius}`; | |
} | |
} | |
class ColoredShape extends Shape { | |
constructor(shape, color) { | |
super(); | |
this.shape = shape; | |
this.color = color; | |
} | |
toString() { | |
return `${this.shape.toString()} tiene el color ${this.color}`; | |
} | |
} | |
class TransparentShape extends Shape { | |
constructor(shape, transparency) { | |
super(); | |
this.shape = shape; | |
this.transparency = transparency; | |
} | |
toString() { | |
return `${this.shape.toString()} y una transparencia de ${ | |
this.transparency * 100.0 | |
}%`; | |
} | |
} | |
let circle = new Circle(2); | |
console.log(circle.toString()); | |
// Un circulo de radio 2 | |
// Decorador | |
let redCircle = new ColoredShape(circle, "rojo"); | |
console.log(redCircle.toString()); | |
// Un circulo de radio 2 tiene el color rojo | |
let redHalfCircle = new TransparentShape(redCircle, 0.5); | |
console.log(redHalfCircle.toString()); | |
// Un circulo de radio 2 tiene el color rojo y una transparencia de 50% |
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
"use strict"; | |
//Integraciones con otros subsistemas | |
class BankHistory { | |
verify(name, amount) { | |
return 200; | |
} | |
} | |
class CreditHistory { | |
get(name) { | |
return []; | |
} | |
} | |
class PersonalProfile { | |
check(name) { | |
return []; | |
} | |
} | |
// Implementación del patrón façade | |
class Loans { | |
constructor(name) { | |
this.name = name; | |
} | |
ApplyFor(amount) { | |
let result = "APROVADO"; | |
// Punto de acceso a multiples subsistemas | |
let bankScore = new BankHistory().verify(this.name, amount); | |
if (bankScore < 500) { | |
result = "RECHAZADO"; | |
} | |
let negativeReports = new CreditHistory().get(this.name); | |
if (negativeReports.length > 0) { | |
result = "RECHAZADO"; | |
} | |
let criminalRecords = new PersonalProfile().check(this.name); | |
if (criminalRecords.length > 0) { | |
result = "RECHAZADO"; | |
} | |
return `${this.name}, su préstamo por valor de ${amount} ha sido ${result}`; | |
} | |
} | |
let prestamos = new Loans("Juanito Alimaña"); | |
console.log(prestamos.ApplyFor(1000000)); | |
// Juanito Alimaña, su préstamo por valor de 1000000 ha sido RECHAZADO |
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
'use strict'; | |
class Point { | |
// Constructor por defecto. | |
constructor(x, y) { | |
this.x = x; | |
this.y = y; | |
} | |
static factory() { | |
return PointFactory; | |
} | |
} | |
class PointFactory { | |
// Factory Method para coordenadas Cartesianas | |
static newCartesianPoint(x, y) { | |
return new Point(x, y); | |
} | |
// Factory Method para coordenadas Polares | |
static newPolarPoint(radio, angulo) { | |
return new Point(radio * Math.cos(angulo), radio * Math.sin(angulo)); | |
} | |
} | |
// Generación de la instancia usando el método factory | |
let cartesianPoint = Point.factory().newCartesianPoint(4, 5); | |
console.log(cartesianPoint); | |
/* | |
Point | |
{ | |
"x": 4, | |
"y": 5 | |
} | |
*/ | |
let polarPoint = Point.factory().newPolarPoint(5, Math.PI / 2); | |
console.log(polarPoint); | |
/* | |
Point | |
{ | |
"x": 3.061616997868383e-16, | |
"y": 5 | |
} | |
*/ |
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
"use strict"; | |
class Event { | |
constructor() { | |
this.handlers = new Map(); | |
this.count = 0; | |
} | |
subscribe(handler) { | |
this.handlers.set(++this.count, handler); | |
return this.count; | |
} | |
unsubscribe(idx) { | |
this.handlers.delete(idx); | |
} | |
// (sender) Quien ejecutó los eventos? | |
// (args) Argumentos adicionales (event args) | |
notify(sender, args) { | |
this.handlers.forEach((func, idx) => func(sender, args)); | |
} | |
} | |
class MarketStore extends Event { | |
constructor(initInventory) { | |
super(); | |
this.inventory = initInventory; | |
} | |
newInventoryArrived(newInventory) { | |
this.inventory = newInventory; | |
console.log(`MarketStore: Nuevo Inventario ha llegado:`, this.inventory); | |
let iPhoneArrived = this.inventory.filter((i) => i === "iPhone 1k"); | |
if (iPhoneArrived.length > 0) { | |
this.notifyIphoneUsers(); | |
} | |
} | |
notifyIphoneUsers() { | |
this.notify( | |
this, | |
`El nuevo iPhone ha llegado, ` + | |
`acercate a nuestras tiendas para llevártelo` | |
); | |
} | |
} | |
class Person { | |
constructor(name) { | |
this.name = name; | |
} | |
update = (sender, args) => { | |
console.log(`Una notificación de ${sender.name} ha llegado!`); | |
console.log(`${this.name}: ${args}`); | |
}; | |
} | |
// Observador | |
let paul = new Person("Paul McCartney"); | |
// Subject | |
let store = new MarketStore([]); | |
store.name = "Los Magníficos Store"; | |
let paulId = store.subscribe(paul.update); | |
//let paulId = store.subscribe(paul.update); | |
// Nuevo Suscriptor Map { 1 => [Function: update] } | |
store.newInventoryArrived(["iPhone 1k", "iPad pro"]); | |
// MarketStore: Nuevo Inventario ha llegado: [ 'iPhone 1k', 'iPad pro' ] | |
/* Llega la notificación */ | |
// Una notificación de Los Magníficos Store ha llegado! | |
// Paul McCartney: El nuevo iPhone ha llegado, acercate a nuestras tiendas para llevártelo | |
store.unsubscribe(paulId); | |
store.newInventoryArrived(["iPhone 1k", "Magic Mouse"]); | |
// MarketStore: Nuevo Inventario ha llegado: [ 'iPhone 1k', 'Magic Mouse' ] | |
/* No han llegado más notificaciones */ |
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
"use strict"; | |
class TrafficLightState { | |
go() { | |
/* Abstract method */ | |
} | |
} | |
class Red extends TrafficLightState { | |
constructor(context) { | |
super(); | |
this.context = context; | |
} | |
go() { | |
console.log(`Red for 1 minute`); | |
this.context.change(new Yellow(this.context)); | |
} | |
} | |
class Yellow extends TrafficLightState { | |
constructor(context) { | |
super(); | |
this.context = context; | |
} | |
go() { | |
console.log(`Yellow for 10 seconds`); | |
this.context.change(new Green(this.context)); | |
} | |
} | |
class Green extends TrafficLightState { | |
constructor(context) { | |
super(); | |
this.context = context; | |
} | |
go() { | |
console.log(`Green for 1 minute`); | |
this.context.change(new Red(this.context)); | |
} | |
} | |
/* Clase Contexto */ | |
class TrafficLight { | |
constructor() { | |
this.count = 0; | |
this.currentState = null; | |
} | |
change(newState) { | |
if (this.count++ >= 10) return; | |
this.currentState = newState; | |
this.currentState.go(); | |
} | |
start(initialState) { | |
this.currentState = initialState; | |
this.currentState.go(); | |
} | |
} | |
let light = new TrafficLight(); | |
let initialState = new Red(light); | |
light.start(initialState); | |
/* | |
Red for 1 minute | |
Yellow for 10 seconds | |
Green for 1 minute | |
Red for 1 minute | |
Yellow for 10 seconds | |
Green for 1 minute | |
Red for 1 minute | |
Yellow for 10 seconds | |
Green for 1 minute | |
Red for 1 minute | |
Yellow for 10 seconds | |
*/ |
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
"use strict"; | |
let OutputFormat = Object.freeze({ | |
markdown: 0, | |
html: 1, | |
}); | |
class ListStrategy { | |
start(buffer) {} | |
end(buffer) {} | |
addListItem(buffer, item) {} | |
} | |
class MarkdownListStrategy extends ListStrategy { | |
addListItem(buffer, item) { | |
buffer.push(` * ${item}`); | |
} | |
} | |
class HtmlListStrategy extends ListStrategy { | |
start(buffer) { | |
buffer.push(`<ul>`); | |
} | |
end(buffer) { | |
buffer.push(`</ul>`); | |
} | |
addListItem(buffer, item) { | |
buffer.push(` <li>${item}</li>`); | |
} | |
} | |
class TextProcessor { | |
constructor(ouputFormat) { | |
this.buffer = []; | |
this.setOutputFormat(ouputFormat); | |
} | |
setOutputFormat(format) { | |
switch (format) { | |
case OutputFormat.markdown: | |
this.listStrategy = new MarkdownListStrategy(); | |
break; | |
case OutputFormat.html: | |
this.listStrategy = new HtmlListStrategy(); | |
break; | |
} | |
} | |
appendList(items) { | |
this.listStrategy.start(this.buffer); | |
for (let item of items) this.listStrategy.addListItem(this.buffer, item); | |
this.listStrategy.end(this.buffer); | |
} | |
// Métodos de útilidad. | |
clear() { | |
this.buffer = []; | |
} | |
toString() { | |
return this.buffer.join("\n"); | |
} | |
} | |
let tp = new TextProcessor(OutputFormat.markdown); | |
tp.appendList([`factory`, `bridge`, `façade`]); | |
console.log(tp.toString()); | |
// * factory | |
// * bridge | |
// * façade | |
tp.clear(); | |
// Cambiamos a otro formato | |
tp.setOutputFormat(OutputFormat.html); | |
tp.appendList(["composite", "decorator", "state"]); | |
console.log(tp.toString()); | |
// <ul> | |
// <li>composite</li> | |
// <li>decorator</li> | |
// <li>state</li> | |
// </ul> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment