Playground - Crea un task manager con patrones de diseño
Clase 77 de 99 • 30 días de JavaScript
Contenido del curso
David Ochoa
David Esteban Giraldo Duque
David Ochoa
David Esteban Giraldo Duque
Leonardo de los angeles Espinoza Hernandez
Joan Alexander Valerio Rodríguez
Angel Javier Sanchez Tenjo
Angel Javier Sanchez Tenjo
Angel Javier Sanchez Tenjo
Rubén Hernández Hernández
Victor Ortiz
Carina Payleman
Osvaldo Martinez Guillen
Alejandro Anaya
JAIME EDUARDO DIAZ TOBON
Frandel Corporan Rodríguez
Harold Zurita Simon
Raul Carrillo Garrido
Elias Rayas Gonzalez
Esteban Alzate Atehortua
Escudo Anti-Spoilers
Authorization.js
export class Authorization { checkAuthorization(user, task) { const isAutorized = task.users.some((task_user) => task_user == user); if (isAutorized) { return true; } throw new Error("No autorizado"); } }
TaskBuilder.js (Version que a mi parecer deberia ser)
A mi parecer para ingresar los campos de deadline y priority se debe hacer uso de una instancia TaskDecorator, ya que por defecto la instancia Task está preparada para recibir solamente el id y description mientras que con TaskDecorator añade más funcionalidades (Justamente la funcion de este sistema de diseño)
import { Task } from "./exercise"; import { TaskDecorator } from "./TaskDecorator"; export class TaskBuilder { constructor() { this.id = undefined; this.description = undefined; this.completed = undefined; this.users = undefined; this.deadline = undefined; this.priority = undefined; } setId(id) { this.id = id; } setDescription(description) { this.description = description; } setCompleted(completed) { this.completed = completed; } setUsers(users) { this.users = users; } setDeadline(deadline) { this.deadline = deadline; } setPriority(priority) { this.priority = priority; } build() { const task = new Task(this.id, this.description); this.users.forEach((user) => task.assignUser(user)); if (this.deadline && this.priority) { const taskDecorator = new TaskDecorator(task, { deadline: this.deadline, priority: this.priority, }); return taskDecorator; } } }
TaskBuilder.js (Con la que apruebas el playground)
Aqui simplemente agrega atributos que no estan presentes en una instancia de Task
import { Task } from "./exercise"; export class TaskBuilder { constructor() { this.id = undefined; this.description = undefined; this.completed = undefined; this.users = undefined; this.deadline = undefined; this.priority = undefined; } setId(id) { this.id = id; } setDescription(description) { this.description = description; } setCompleted(completed) { this.completed = completed; } setUsers(users) { this.users = users; } setDeadline(deadline) { this.deadline = deadline; } setPriority(priority) { this.priority = priority; } build() { const task = new Task(this.id, this.description); this.users.forEach((user) => task.assignUser(user)); task.deadline = this.deadline task.priority = this.priority return task; } }
TaskDecorator.js
export class TaskDecorator { constructor(task, options) { this.task = task; this.priority = ""; this.deadline = ""; this.checkDeadlineFormat(options.deadline); this.checkPriority(options.priority); } checkDeadlineFormat(deadline) { const regex = /\d{4}-\d{2}-\d{2}/; const isValidFormat = regex.test(deadline); if (isValidFormat) { this.deadline = deadline; } else { this.deadline = "2023-04-19"; } } checkPriority(priority) { const options = ["high", "medium", "low", "alta", "media", "baja"]; const isValidPriority = options.some( (option) => option == priority.toLowerCase() ); if (isValidPriority) { this.priority = priority.toLowerCase(); } else { this.priority = "baja"; } } assignUser(user) { if (user instanceof User) { this.task.assignUser(user); } else { throw new Error("Debe pasar como parametro una instancia de User"); } } completeTask() { this.task.completeTask(); } notifyUsers() { this.task.notifyUsers(); } }
TaskManager.js
import { Task } from "./exercise"; export class TaskManager { constructor() { this.tasks = []; } static getInstance() { if (!TaskManager.instance) { TaskManager.instance = new TaskManager(); } return TaskManager.instance; } addTask(task) { if (task instanceof Task) { this.tasks.push(task); } else { throw new Error("Debe pasar como parámetro una instancia de tarea"); } } getTasks() { return this.tasks; } getTaskById(id) { const task = this.tasks.find((task) => task.id == id); return task ? task : null; } }
export class User { constructor(name) { this.name = name; } notify(task) { return `La tarea ${task.id} fue completada`; } }
exercise.js
import { User } from "./User" export class Task { constructor(id, description) { this.id = id; this.description = description; this.completed = false; this.users = []; } assignUser(user) { if (user instanceof User) { this.users.push(user); } else { throw new Error("Debe pasar como parametro una instancia de User"); } } completeTask() { this.completed = true; this.notifyUsers(); } notifyUsers() { this.users.forEach((user) => user.notify(this)); } }
Pensé lo mismo con la clase TaskBuilder. P.D.: Geniales las validaciones que hiciste para deadline y priority.
Pensé que le faltaría algo si no se ponían validaciones 😂
Mi solución: .
. . . . .
Authorization.js
export class Authorization { checkAuthorization(user, task) { if (task.users.includes(user)) { task.completeTask() } else { throw new Error("No autorizado") } } }
TaskBuilder.js
import { Task } from "./exercise"; export class TaskBuilder { constructor() { this.task = new Task(0, "") } setId(id) { this.task.id = id return this } setDescription(description) { this.task.description = description return this } setCompleted(completed) { this.task.completed = completed return this } setUsers(users) { this.task.users.push(...users) return this } setDeadline(deadline) { this.task.deadline = deadline return this } setPriority(priority) { this.task.priority = priority return this } build() { return this.task } }
TaskDecorator.js
export class TaskDecorator { constructor(task, options) { this.task = task this.deadline = options.deadline this.priority = options.priority } assignUser(user) { this.task.assignUser(user) } completeTask() { this.task.completeTask( } notifyUsers() { this.task.notifyUsers(this) } }
TaskManager.js
import { Task } from "./exercise"; export class TaskManager { constructor() { } static getInstance() { if (!TaskManager.instance) { TaskManager.tasks = [] TaskManager.instance = new TaskManager() } return TaskManager.instance } addTask(task){ if (task instanceof Task) { TaskManager.tasks.push(task) } } getTasks(){ return TaskManager.tasks } getTaskById(id){ return TaskManager.tasks.find(task => task.id === id) || null } }
User.js
export class User { constructor(name) { this.name = name } notify(task) { console.log(`${this.name} ha sido notificado de que la tarea ${task.id} se completó`) } }
exercise.js
import { User } from "./User" export class Task{ constructor(id, description){ this.id = id this.description = description this.completed = false this.users = [] } assignUser(user){ if (user instanceof User) { this.users.push(user) } else { throw new Error("El usuario no existe") } } completeTask() { this.completed = true this.notifyUsers() } notifyUsers() { this.users.forEach(user => user.notify(this)) } }
Gracias por el feedback! 💪 Me pongo ya mismo a corregir el ejercicio 🙌
Es necesario hacer este comentario, porque el tiempo que se pierde tratando de resolver un posible "error" que tenemos en nuestro código, cuando realmente el error proviene de una documentación que no aclara todos los requerimientos del ejercicio es extremadamente molesto.
Por favor equipo Platzi e instructor, se requiere que este curso completo se verifique, documentaciones, ejercicios, etc. Es muy frecuente la presencia de errores en todo. Esto lo hago como recomendación porque imagínense si para uno es molesto que tiene experiencia en el area, que ha de ser para una persona que esta iniciando en el mundo del desarrollo.
Esto es lo único negativo que puedo mencionar del curso, mala documentación en muchos casos.
🫤 mi solución.....
Hola comparto la solución:
✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅
Authorization.js
export class Authorization { checkAuthorization(user, task) { if (!task.users.includes(user)) { throw new Error("No autorizado"); } } }
TaskDecorator.js
export class TaskDecorator { constructor(task, options) { this.task = task; this.deadline = options.deadline; this.priority = options.priority; } assignUser(user) { this.task.assignUser(user); } completeTask() { this.task.completeTask(); } notifyUsers() { this.task.notifyUsers(); } }
TaskManager.js
import { Task } from "./exercise"; export class TaskManager { constructor() { this.tasks = []; } static getInstance() { if (!TaskManager.instance) { TaskManager.instance = new TaskManager(); } return TaskManager.instance; } addTask(task) { this.tasks.push(task); } getTasks() { return this.tasks; } getTaskById(id) { const task = this.tasks.filter((task) => task.id === id)[0]; if (task) { return task; } return null; } }
User.js
export class User { constructor(name) { this.name = name; } notify(task) { console.log( `Usuario ${this.name}: La tarea "${task.description}" ha sido completada.` ); } }
💚Mi solución 💚
🛡️MURO ANTI-SPOILERS🛡️
exercise.js (Task)
import { User } from "./User" export class Task{ constructor(id, description) { this.id = id this.description = description this.completed = false this.users = [] } assignUser(user) { if (!(user instanceof User)) throw new Error("Not a user") this.users.push(user) } completeTask() { this.completed = true this.notifyUsers() } notifyUsers() { this.users.forEach(user => user.notify(this)) } }
User.js
export class User { constructor(name) { this.name = name } notify(task) { console.log(`El usuario ${name} ha sido notificado de que "${task.id}:${task.description}" ha sido completada.`) } }
Authorization.js
export class Authorization { checkAuthorization(user, task) { let indexOfUser = task.users.indexOf(user) if (indexOfUser === -1) throw new Error('No autorizado') } }
TaskDecorator.js
export class TaskDecorator { constructor(task, options) { this.task = task this.deadline = options.deadline this.priority = options.priority } assignUser(user) { this.task.assignUser(user) } completeTask() { this.task.completeTask() } notifyUsers() { this.task.notifyUsers() } }
TaskBuilder.js
import { Task } from "./exercise"; export class TaskBuilder { constructor() { this.task = new Task('', '') } setId(id) { this.task.id = id return this.task } setDescription(description) { this.task.description = description return this.task } setCompleted(completed) { this.task.completed = completed return this.task } setUsers(users) { this.task.users = users return this.task } setDeadline(deadline) { this.task.deadline = deadline return this.task } setPriority(priority) { this.task.priority = priority return this.task } build() { return this.task } }
TaskManager.js
import { Task } from "./exercise"; export class TaskManager { constructor() { if (!TaskManager.instance) { this.tasks = [] TaskManager.instance = Object.freeze(this) } return TaskManager.instance } static getInstance() { return new TaskManager() } addTask(task) { if (!(task instanceof Task)) throw new Error("Not a Task") this.tasks.push(task) } getTasks() { return this.tasks } getTaskById(id) { return this.tasks.find(task => task.id === id) || null } }
Algo difícil, pero esta hecho: . . . . . . . . . . . . . . . . . . . . . .
exercise.js
import { User } from "./User" export class Task{ constructor(id, description) { // Tu código aquí 👈 this.id = id; this.description = description; this.completed = false; this.users = []; } assignUser(user) { // Tu código aquí 👈 if (!(user instanceof User)) throw new Error("No existe el usuario a registrar"); this.users.push(user); } completeTask() { // Tu código aquí 👈 this.completed = true; this.notifyUsers(); } notifyUsers() { // Tu código aquí 👈 for (let user of this.users) user.notify(this); } }
User.js
export class User { constructor(name) { // Tu código aquí 👈 this.name = name; } notify(task) { // Tu código aquí 👈 return `La tarea ${task.id} fue completada`; } }
TaskManager.js
import { Task } from "./exercise"; export class TaskManager { constructor() { // Tu código aquí 👈 this.tasks = []; } static getInstance() { // Tu código aquí 👈 if (!TaskManager.instance) { TaskManager.instance = new TaskManager(); } return TaskManager.instance; } addTask(task) { // Tu código aquí 👈 if (!(task instanceof Task)) throw new Error('Tarea no valida'); this.tasks.push(task); } getTasks() { // Tu código aquí 👈 return this.tasks; } getTaskById(id) { // Tu código aquí 👈 if (this.tasks.some(task => task.id === id)) return this.tasks.find(task => task.id === id); else return null; } }
TaskDecorator.js
export class TaskDecorator { constructor(task, options) { // Tu código aquí 👈 this.task = task; this.deadline = options.deadline; this.priority = options.priority; } assignUser(user) { // Tu código aquí 👈 if (!(user instanceof User)) throw new Error('No es una instancia de User'); this.task.assignUser(user); } completeTask() { // Tu código aquí 👈 this.task.completeTask(); } notifyUsers() { // Tu código aquí 👈 this.task.notifyUsers(this); } }
TaskBuilder.js
import { Task } from "./exercise"; export class TaskBuilder { constructor() { // Tu código aquí 👈 this.id = undefined; this.description = ''; this.completed = undefined; this.users = []; this.deadline = ''; this.priority = ''; } setId(id) { // Tu código aquí 👈 this.id = id; } setDescription(description) { // Tu código aquí 👈 this.description = description; } setCompleted(completed) { // Tu código aquí 👈 this.completed = completed; } setUsers(users) { // Tu código aquí 👈 this.users = users; } setDeadline(deadline) { // Tu código aquí 👈 this.deadline = deadline; } setPriority(priority) { // Tu código aquí 👈 this.priority = priority; } build() { // Tu código aquí 👈 const task = new Task(this.id, this.description); this.users.forEach(user => task.assignUser(user)); task.deadline = this.deadline; task.priority = this.priority; return task; } }
Authorization.js
export class Authorization { checkAuthorization(user, task) { // Tu código aquí 👈 if (!task.users.some(tkuser => tkuser === user)) throw new Error('No autorizado'); return true; } }
exercise.js:
(OBSERVER)
import { User } from "./User" //Con patrón OBSERVER -- Observable: export class Task{ constructor(id, description){ this.id = id; this.description = description; this.completed = false; this.users = []; } assignUser(user) { if (user instanceof User) { this.users.push(user); } else { throw new Error("Usuario no encontrado.") } } completeTask() { this.completed = true; this.notifyUsers(); } notifyUsers() { this.users.forEach(user => user.notify(this)); } }
User.js:
(OBSERVER)
//Con patrón OBSERVER -- Observador: export class User { constructor(name) { this.name = name; } notify(task) { console.log(`La tarea ${task.id} fue completada con éxito.`) } }
TaskManager.js:
(SINGLETON)
import { Task } from "./exercise"; //Con patrón SINGLETON: export class TaskManager { constructor() {} static getInstance() { if (!TaskManager.instance) { this.tasks = []; TaskManager.instance = new TaskManager(); } return TaskManager.instance; } addTask(task){ if (task instanceof Task) { TaskManager.tasks.push(task); } else { throw new Error("Tarea inválida.") } } getTasks(){ return TaskManager.tasks; } getTaskById(id) { return TaskManager.tasks.find(task => task.id === id) || null } }
TaskDecorator.js:
(DECORATOR)
//Con DECORATOR PATTERN: export class TaskDecorator { constructor(task, options) { this.task = task; this.deadline = options.deadline; this.priority = options.priority; } assignUser(user) { this.task.assignUser(user); } completeTask() { this.task.completeTask(); } notifyUsers() { this.task.notifyUsers(this); } }
TaskBuilder.js:
(BUILDER)
import { Task } from "./exercise"; //Con BUILDER PATTERN: export class TaskBuilder { constructor() { this.task = new Task(0, "") } setId(id) { this.task.id = id; return this; } setDescription(description) { this.task.description = description; return this; } setCompleted(completed) { this.task.completed = completed; return this; } setUsers(users) { this.task.users.push(...users); return this; } setDeadline(deadline) { this.task.deadline = deadline; return this; } setPriority(priority) { this.task.priority = priority; return this; } build() { return this.task; } }
Authorization.js:
(PROXY)
//Con patrón PROXY: export class Authorization { checkAuthorization(user, task) { if (task.users.includes(user)) { return true; } else { throw new Error("No autorizado.") } } }
Listo
++exercise.js++
import { User } from "./User" export class Task { constructor(id, description) { this.id = id; this.description = description; this.completed = false; this.users = []; } assignUser(user) { if (user instanceof User) { this.users.push(user); } else { throw new Error("Isnt a user instance"); } } completeTask() { this.completed = true; this.notifyUsers(); } notifyUsers() { this.users.forEach(user => user.notify(this)); } }
++User.js++
export class User { constructor(name) { this.name = name; } notify(task) { return `The task with ID ${task.id} has been completed by ${this.user}`; } }
++TaskManager.js++
import { Task } from "./exercise"; export class TaskManager { constructor() { if (!TaskManager.instance) { this.tasks = [] TaskManager.instance = Object.freeze(this) } return TaskManager.instance } static getInstance() { return new TaskManager() } addTask(task) { if (task instanceof Task) { this.tasks.push(task); } else { throw Error(`Not is a instance of Task`); } } getTasks() { return this.tasks; } getTaskById(id) { let search = this.tasks.findIndex(task => task.id === id); if (!search) { return this.tasks[search]; } return null; } }
++TaskDecorator.js++
export class TaskDecorator { constructor(task, options) { this.task = task; this.deadline = options.deadline; this.priority = options.priority; } assignUser(user) { this.task.assignUser(user); } completeTask() { this.task.completeTask(); } notifyUsers() { this.task.notifyUsers(); } }
++TaskBuilder++
import { Task } from "./exercise"; export class TaskBuilder { constructor() { this.id = ''; this.description = ''; this.completed = ''; this.users = []; this.deadline = ''; this.priority = ''; } setId(id) { this.id = id; return this; } setDescription(description) { this.description = description; return this; } setCompleted(completed) { this.completed = completed; return this; } setUsers(users) { users.forEach(user => this.users.push(user)); return this; } setDeadline(deadline) { this.deadline = deadline; return this; } setPriority(priority) { this.priority = priority; return this } build() { let task = new Task( this.id, this.description ); this.users.forEach(user => task.assignUser(user)); task.completed = this.completed, task.deadline = this.deadline; task.priority = this.priority; return task; } }
++Authorization.js++
export class Authorization { checkAuthorization(user, task) { if (task.users.includes(user)) { return `Authorized`; } else { throw Error("Not authorized"); } } }
🛡️🛡️Escudo anti-spoilers🛡️🛡️ Mi solución al reto:
exercise.js
import { User } from "./User" export class Task{ constructor(id, description) { this.id = id this.description = description this.completed = false this.users = []; } assignUser(user) { if (!(user instanceof User)) throw new Error('no es instancia de User') this.users.push(user) } completeTask() { this.completed = true; this.notifyUsers() } notifyUsers() { for (let user of this.users) { user.notify(this) } } }
User.js
export class User { constructor(name) { this.name = name } notify(task) { console.log(`La tarea '${task.name}' fue completada`) } }
TaskManager.js
import { Task } from "./exercise"; export class TaskManager { constructor() { this.tasks = [] } static getInstance() { if (!TaskManager.instance) { TaskManager.instance = new TaskManager(); } return TaskManager.instance; } addTask(task){ if(!task instanceof Task) throw new Error("No es una instancia de Task"); this.tasks.push(task) } getTasks(){ return this.tasks } getTaskById(id) { return this.tasks.find(t => t.id === id) || null; } }
taskDecorator.js
import { Task } from "./exercise.js" export class TaskDecorator extends Task{ constructor(task, options) { super(task) this.task = task this.priority = options.priority this.deadline = options.deadline } assignUser(user) { console.log('Asignando usuario...') this.task.assignUser(user) } completeTask() { console.log('Marcando la tarea como completada...') this.task.completeTask() } notifyUsers() { console.log('Notificando a todos los usuarios...') this.task.notifyUsers() } }
TaskBuilder.js
import { Task } from "./exercise"; export class TaskBuilder extends Task{ constructor(task) { super(task) } setId(id) { this.id = id; return this } setDescription(description) { this.description = description; return this } setCompleted(completed) { this.completed = completed; return this } setUsers(users) { this.users = users; return this } setDeadline(deadline) { this.deadline = deadline; return this } setPriority(priority) { this.priority = priority; return this } build() { return this } }
Authorization.js
export class Authorization { checkAuthorization(user, task) { let exist = task.users.filter(u => user === u).length > 0 if (!exist) throw new Error('Usuario no autorizado') return exist } }
++MI SOLUCION++ 💪 . . . . . . . . . . . . . . . . . . class Task
import { User } from "./User" export class Task { constructor(id, description){ this.id = id; this.description = description; this.completed = false; this.users = []; } assignUser(user){ if (user instanceof User) { this.users.push(user); } else { throw new Error("user no es una instancia de User"); } } completeTask() { this.completed = true; this.notifyUsers(); } notifyUsers() { this.users.forEach(user => user.notify(this)); } }
class Authorization
export class Authorization { checkAuthorization(user, task) { const isAuthorized = task.users.some(taskUser => taskUser === user); if (isAuthorized) return true; throw new Error("No autorizado");; } }
class TaskDecorator
export class TaskDecorator { constructor(task, options) { this.task = task; this.priority = ""; this.deadline = ""; this.checkDeadlineFormat(options.deadline); this.checkPriority(options.priority); } checkDeadlineFormat(deadline) { const regex = /\d{4}-\d{2}-\d{2}/; const isValidFormat = regex.test(deadline); if (isValidFormat) { this.deadline = deadline; } else { this.deadline = "2023-04-30"; } } checkPriority(priority) { const options = ["high", "medium", "low", "alta", "media", "baja"]; const isValidPriority = options.some(option => option == priority.toLowerCase() ); if (isValidPriority) { this.priority = priority.toLowerCase(); } else { throw new Error("priority incorrecta"); } } assignUser(user) { this.task.assignUser(user); } completeTask() { this.task.completeTask(); } notifyUsers() { this.task.notifyUsers(); } }
class TaskBuilder
import { Task } from "./exercise"; export class TaskBuilder { constructor() { this.id = undefined; this.description = undefined; this.completed = undefined; this.users = undefined; this.deadline = undefined; this.priority = undefined; } setId(id) { this.id = id; } setDescription(description) { this.description = description; } setCompleted(completed) { this.completed = completed; } setUsers(users) { this.users = users; } setDeadline(deadline) { this.deadline = deadline; } setPriority(priority) { this.priority = priority; } build() { const task = new Task(this.id, this.description); this.users.forEach(user => task.assignUser(user)); task.deadline = this.deadline task.priority = this.priority return task; } }
class TaskManager
import { Task } from "./exercise"; export class TaskManager { constructor() { this.tasks = []; } static getInstance() { if(!TaskManager.instance) TaskManager.instance = new TaskManager(); return TaskManager.instance; } addTask(task){ if (task instanceof Task) { this.tasks.push(task); } else { throw new Error("task incorrecta"); } } getTasks(){ return this.tasks; } getTaskById(id){ const task = this.tasks.find(task => task.id == id); return task ? task : null; } }
Aqui voy:
Autorization:
export class Authorization { checkAuthorization(user, task) { if (task.users.includes(user)) { return 'Autorizado' } else { throw new Error('No autorizado') } } }
TaskBuilder:
import { Task } from "./exercise.js"; export class TaskBuilder extends Task { constructor(task) { super(task) } setId(id) { super.id = id return this } setDescription(description) { super.description = description return this } setCompleted(completed) { super.completed = completed return this } setUsers(users) { for (let user in users) { super.assignUser(users[user]) } return this } setDeadline(deadline) { super.deadline = deadline return this } setPriority(priority) { super.priority = priority return this } build() { return this } }
TaskDecorator:
export class TaskDecorator { constructor(task, options) { this.task = task; this.deadline = options.deadline; this.priority = options.priority; } assignUser(user) { this.task.assignUser(user); } completeTask() { this.task.completeTask(); } notifyUsers() { this.task.notifyUsers(); } }
TaskManager:
import { Task } from "./exercise.js"; export class TaskManager { constructor() { if (!TaskManager.instance) { this.tasks = [] TaskManager.instance = Object.freeze(this) } return TaskManager.instance } static getInstance() { return new TaskManager() } addTask(task) { task instanceof Task ? this.tasks.push(task) : new Error('no es una tarea o no hereda de Task') } getTasks() { return this.tasks } getTaskById(id) { return this.tasks.find(task => task.id === id) || null } }
User:
export class User { constructor(name) { this.name = name } notify(task) { return `${this.name}: La tarea (${task.description}) ha sido completada` } }
exercise:
import { User } from "./User.js" export class Task { constructor(id, description) { this.id = id this.description = description this.users = [] this.completed = false } assignUser(user) { if (user instanceof User) this.users.push(user) else throw new Error('no es user') } completeTask() { this.completed = true return this.notifyUsers() } notifyUsers() { const responses = [] this.users.forEach(user => responses.push(user.notify(this))) return responses.join('\n') } }
Solución… 😄 . . . .
export class Authorization { checkAuthorization(user, task) { const authorized = task.users.includes(user); if (authorized) { return true; } throw new Error("El usuario no está autorizado para esta tarea"); } }
. TaskBuilder.js: .
import { Task } from "./exercise"; export class TaskBuilder { constructor() { this.task = new Task(); } setId(id) { this.task.id = id; return this; } setDescription(description) { this.task.description = description; return this; } setCompleted(completed) { this.task.completed = completed; return this; } setUsers(users) { this.task.users = users; return this; } setDeadline(deadline) { this.task.deadline = deadline; return this; } setPriority(priority) { this.task.priority = priority; return this; } build() { return this.task; } }
. TaskDecorator.js: .
export class TaskDecorator { constructor(task, options) { this.task = task; this.deadline = options.deadline; this.priority = options.priority; } assignUser(user) { this.task.assignUser(user); } completeTask() { this.task.completeTask(); } notifyUsers() { this.task.notifyUsers(); } }
. TaskManager.js: .
import { Task } from "./exercise"; export class TaskManager { constructor() { this.tasks = []; } static getInstance() { if (!TaskManager.instance) { TaskManager.instance = new TaskManager(); } return TaskManager.instance; } addTask(task) { if (task instanceof Task) { this.tasks.push(task); } } getTasks() { return this.tasks; } getTaskById(id) { return this.tasks.find(task => task.id === id) || null; } }
. User.js: .
export class User { constructor(name) { this.name = name; } notify(task) { return `${this.name} ha sido notificado: la tarea ${task.id} ha sido completada`; } }
. exercise.js: .
import { User } from "./User" export class Task { constructor(id, description) { this.id = id; this.description = description; this.completed = false; this.users = []; } assignUser(user) { if (user instanceof User) { this.users.push(user); } else { throw new Error("Se debe asignar una instancia de usuario"); } } completeTask() { this.completed = true; this.notifyUsers(); } notifyUsers() { this.users.forEach(user => user.notify(this)); } }
Definitivamente aun tengo que amueblar el cerebro para trabajar con JS "multicapa retorcida" xD
, , , , , , ,
import { Task } from "./exercise"; export class TaskBuilder { constructor() { this.task = new Task(); } setId(id) { this.task.id = id; return this; } setDescription(description) { this.task.description = description; return this; } setCompleted(completed) { this.task.completed = completed; return this; } setUsers(users) { this.task.users = users; return this; } setDeadline(deadline) { this.task.deadline = deadline; return this; } setPriority(priority) { this.task.priority = priority; return this; } build() { return this.task; } }
import { User } from "./User" export class Task { constructor(id, description) { this.id = id; this.description = description; this.completed = false; this.users = []; } assignUser(user) { if(!(user instanceof User)){ throw new Error("No hereda de la clase user") } this.users.push(user); } completeTask() { this.completed = true; this.notifyUsers(); } notifyUsers() { this.users.forEach(user => { user.notify(this); }); } }
export class User { constructor(name) { this.name = name; } notify(task) { console.log(`La tarea ${task.description} ha sido completada`); } }
import { Task } from "./exercise"; export class TaskManager { constructor() { this.tasks = []; } static getInstance() { if (!TaskManager.instance) { TaskManager.instance = new TaskManager(); } return TaskManager.instance; } addTask(task) { if (task instanceof Task) { this.tasks.push(task); } else { throw new Error('La tarea no es válida'); } } getTasks() { return this.tasks; } getTaskById(id) { return this.tasks.find(task => task.id === id) || null; } }
export class TaskDecorator { constructor(task, options) { this.task = task this.deadline = options.deadline; this.priority = options.priority; } assignUser(user) { this.task.assignUser(user); } completeTask() { this.task.completeTask(); } notifyUsers() { this.task.notifyUsers(); } }
Solución
Authorization
export class Authorization { checkAuthorization(user, task) { // Tu código aquí 👈 const isAuthenticated = task.users.findIndex((taskUser) => taskUser.name === user.name) !== -1; if (!isAuthenticated) throw Error("Not authorized"); console.log(`User: ${user.name} is authorized`); task.completeTask(); } }
exercise
import { User } from "./User.mjs"; export class Task { constructor(id, description) { // Tu código aquí 👈 this.id = id; this.description = description; this.completed = false; this.users = []; } assignUser(user) { // Tu código aquí if (user instanceof User) { this.users.push(user); return this.users; } } completeTask() { // Tu código aquí 👈 if (this.users.length === 0) { console.log("Cannot complete task, no user assigned to this task"); return; } this.completed = true; this.notifyUsers(); } notifyUsers() { // Tu código aquí 👈 this.users.forEach((user) => user.notify(this)); } }
TaskBuilder
import { Task } from "./excercise.mjs"; export class TaskBuilder { constructor() { // Tu código aquí 👈 this.id = 0; this.description = ""; this.completed = false; this.users = []; this.deadline = null; this.priority = null; } setId(id) { // Tu código aquí 👈 this.id = id; return this; } setDescription(description) { // Tu código aquí 👈 this.description = description; return this; } setCompleted(completed) { // Tu código aquí 👈 this.completed = completed; return this; } setUsers(users) { // Tu código aquí 👈 this.users = users; return this; } setDeadline(deadline) { // Tu código aquí 👈 this.deadline = deadline; return this; } setPriority(priority) { // Tu código aquí 👈 this.priority = priority; return this; } build() { // Tu código aquí 👈 const task = new Task(this.id, this.description); this.users.forEach((user) => task.assignUser(user)); task.priority = this.priority; task.deadline = this.deadline; return task; } }
TaskDecorator
export class TaskDecorator { constructor(task, options) { // Tu código aquí 👈 this.task = task; this.deadline = options.deadline; this.priority = options.priority; } assignUser(user) { // Tu código aquí 👈 this.task.assignUser(user); } completeTask() { // Tu código aquí 👈 this.task.completeTask(); } notifyUsers() { // Tu código aquí 👈 this.task.notifyUsers(); } }
TaskManager
import { Task } from "./excercise.mjs"; export class TaskManager { static instance = null; constructor() { // Tu código aquí 👈 this.tasks = []; } static getInstance() { // Tu código aquí 👈 if (TaskManager.instance === null) { TaskManager.instance = new TaskManager(); } return TaskManager.instance; } addTask(task) { // Tu código aquí 👈 if (!(task instanceof Task)) return; if ( this.tasks.findIndex((managerTask) => managerTask.id === task.id) !== -1 ) { throw Error("This task already exists in the Task manager"); } this.tasks.push(task); console.log(`Task added: ${task.description}`); } getTasks() { // Tu código aquí if (this.tasks.length === 0) { console.log("The tasks list is empty"); return; } console.log(this.tasks); return this.tasks; } getTaskById(id) { // Tu código aquí 👈 const task = this.tasks.find((task) => task.id === id); console.log(task); return task ? task : null; } }
User
export class User { constructor(name) { // Tu código aquí 👈 this.name = name; } notify(task) { // Tu código aquí 👈 console.log(`The task: ${task?.description} is completed.`); } }
Se logró :D, sude la gota amarga pero se logró: . . . . . . . . . . . . . . . . . . . .
Authorization.js
export class Authorization { checkAuthorization(user, task) { if (task.users.includes(user)) { task.completeTask(); } else { throw new Error("El usuario no esta autorizado para completar la tarea"); } } }
TaskBuilder.js
import { Task } from "./exercise"; export class TaskBuilder { constructor() { this.task = new Task(); } setId(id) { this.task.id = id; return this; } setDescription(description) { this.task.description = description; return this; } setCompleted(completed) { this.task.completed = completed; return this; } setUsers(users) { this.task.users = users; return this; } setDeadline(deadline) { this.task.deadline = deadline; return this; } setPriority(priority) { this.task.priority = priority; return this; } build() { return this.task } }
TaskDecorator.js
export class TaskDecorator { constructor(task, options) { this.task = task; this.deadline = options.deadline; this.priority = options.priority; } assignUser(user) { this.task.assignUser(user); } completeTask() { this.task.completeTask(); } notifyUsers() { this.users.forEach(user => { user.notify(this) }) } }
TaskManager.js
import { Task } from "./exercise"; export class TaskManager { constructor() { this.tasks = []; } static getInstance() { if (!TaskManager.instance) { TaskManager.instance = new TaskManager(); } return TaskManager.instance; } addTask(task) { if (task instanceof Task) { this.tasks.push(task); } else { throw new Error(`La tarea no es valida`) } } getTasks() { return this.tasks; } getTaskById(id) { let foundTask = this.tasks.find(task => task.id === id); if (foundTask) { return foundTask; } else { return null; } } }
User.js
export class User { constructor(name) { this.name = name; } notify(task) { return `La tarea ${task} ha sido completada`; } }
excercise.js
import { User } from "./User" export class Task { constructor(id, description) { this.users = []; this.id = id; this.description = description; this.completed = false; } assignUser(user) { if (user instanceof User) { this.users.push(user); } else { throw new Error(`No se puede asignar si no es de la clase User`) } } completeTask() { this.completed = true; this.notifyUsers(); } notifyUsers() { this.users.forEach(user => { user.notify(this) }) } }