No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Factory pattern y RORO

12/20
Recursos

Factory pattern (o f谩brica de objeto) y RORO (Recibir un Objeto, Retornar un Objeto) son dos patrones que nos ayudan a crear moldes de objetos a partir de funciones. Con ello ya no ser铆a necesario utilizar objetos literales ni deep copy con recursividad.

Generando objetos a partir de funciones

Generaremos una funci贸n que nos permita generar nuevos estudiantes. Esta funci贸n va a recibir un objeto (con los datos del nuevo estudiante) como par谩metro y devolver谩 el nuevo objeto generado.

function isObject(subject) {
  return typeof subject == "object";
}

function isArray(subject) {
  return Array.isArray(subject);
}

function createStudent({
  name,
  email,
  age,
  twitter,
  instagram,
  facebook,
  approvedCourses,
  learningPaths,
}) {
  return {
    name,
    email,
    age,
    approvedCourses,
    learningPaths,
    socialMedia: {
      twitter,
      instagram,
      facebook,
    },
  };
}

Antes de crear nuevos objetos, podr铆amos darles unas mejoras a nuestra funci贸n:

  1. Los atributos approvedCourses y learningPaths deber铆an ser arreglos vac铆os por defecto y as铆 evitamos que sean undefined en caso de que no se env铆en datos en el momento que se genere un nuevo estudiante:

    function isObject(subject) {
      return typeof subject == "object";
    }
    
    function isArray(subject) {
      return Array.isArray(subject);
    }
    
    function createStudent({
      name,
      email,
      age,
      twitter,
      instagram,
      facebook,
      approvedCourses = [], // 馃憟馃憟
      learningPaths = [], // 馃憟馃憟
    }) {
      return {
        name,
        email,
        age,
        approvedCourses,
        learningPaths,
        socialMedia: {
          twitter,
          instagram,
          facebook,
        },
      };
    }
    
  2. Si en caso de invocar a la funci贸n createStudent no mandamos siquiera un objeto vac铆o como argumento, nos dar谩 un error. Evitemos esto declarando que el par谩metro que recibe la funci贸n puede ser un objeto vac铆o por defecto:

    function isObject(subject) {
      return typeof subject == "object";
    }
    
    function isArray(subject) {
      return Array.isArray(subject);
    }
    
    function createStudent({
      name,
      email,
      age,
      twitter,
      instagram,
      facebook,
      approvedCourses = [],
      learningPaths = [],
    } = {}) { // 馃憟馃憟
      return {
        name,
        email,
        age,
        approvedCourses,
        learningPaths,
        socialMedia: {
          twitter,
          instagram,
          facebook,
        },
      };
    }
    
  3. Deber铆amos hacer que algunos campos como email sean obligatorios de enviar, pues, no todos los atributos se deber铆an quedar como undefined ni tampoco deber铆amos poner valores por defecto a ciertos datos personales de un estudiante. Por tanto, deber铆amos avisar mediante un mensaje de error personalizado que ciertos campos son obligatorios:

    function isObject(subject) {
      return typeof subject == "object";
    }
    
    function isArray(subject) {
      return Array.isArray(subject);
    }
    
    // Creamos una funci贸n con el objetivo de generar un Error el cual
    // tendr谩 un mensaje customizado por nosotros.
    // Como par谩metro indicamos el nombre del atributo que no se est谩 enviando (String)
    function requiredParam(param) { // 馃憟馃憟
      throw new Error(param + " es obligatorio"); // Este es el mensaje de error generado
    }
    
    function createStudent({
    	// Por defecto, invocamos a la nueva funci贸n requiredParam en aquellos
    	// atributos que deseamos que sean obligatorios. Indicamos como argumento el nombre
    	// de dicho atributo.
      name = requiredParam("name"), // 馃憟馃憟
      email = requiredParam("email"), // 馃憟馃憟
      age,
      twitter,
      instagram,
      facebook,
      approvedCourses = [],
      learningPaths = [],
    } = {}) {
      return {
        name,
        email,
        age,
        approvedCourses,
        learningPaths,
        socialMedia: {
          twitter,
          instagram,
          facebook,
        },
      };
    }
    

    Ahora, si intentamos crear un objeto que no tenga, por ejemplo, asignado un valor en la propiedad name, la consola nos mostrar谩 el mensaje de error que creamos:

    const juan = createStudent({ email: "[email protected]"});
    
    La consola nos muestra un mensaje con formato de Error diciendo que el atributo name es obligatorio

    Aprendamos ahora a c贸mo crear propiedades privadas en JavaScript. 馃懆鈥嶐煉火煔

    Contribuci贸n creada por: Mart铆n 脕lvarez (Platzi Contributor)

Aportes 29

Preguntas 8

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Al escuchar RORO fue lo primero que se me vino a la cabeza. xD

RORO PIRRORO

Factory pattern y RORO

Lectura muy mucho importante!

Elegant patterns in modern JavaScript: RORO

C贸digo Clase

/* Codigo Deep Copy */

// Requerimientos de parametros obligatorios
function requiredParam(param){
    throw new Error(param + " Campo obligatorio");
}

// Fabrica de estudiantes
function createStudent({
    name = requiredParam("name"),
    email = requiredParam("email"),
    age,
    twitter,
    instagram,
    facebook,
    approvedCourses = [],
    learningPaths = [],
} = {}) {
    return {
        name,
        age,
        email,
        approvedCourses,
        learningPaths,
        socialMedia: {
            twitter,
            instagram,
            facebook,
        },
    };
}

const carlos = createStudent({
    name: 'Carlito',
    age: 20,
    email: '[email protected]',
    twitter: 'carlitosmzz',
}); // {}

Comparto el c贸digo usando TS 馃挋

En Typescript podemos declarar interfaces (es algo as铆 como un contrato para crear un objeto), y declarar propiedades que sean opcionales con el signo de interrogaci贸n 鈥?鈥, las dem谩s ser谩n obligatorias, en caso de no cumplir con el contrato, el lenguaje te avisara antes de ejecutar el c贸digo. 馃榾

.


Este curso, de lejos, se queda como de los mejores, Juan es todo un crack, tanto ense帽ando como sabiendo que ense帽ar 馃槷

**RORO **= Recibir un Objecto, y Retornamos otro Objecto.

Dentro de una funci贸n, recibimos un solo par谩metro que es un objecto, el cual internamente contiene varias propiedades, con las cuales retornara otro nuevo objeto.

Recibir un objeto, retornar un objeto, anotado

7 FACTORY PATTERN Y RORO

RORO es un patr贸n de dise帽o que consiste en crear una funci贸n que devuelve un objeto.
RO -> Recibir un objeto
RO -> Retornar un objeto

function requiredParam(param){
    throw new Error(param + "missing parameter")
}

el c贸digo anterior es una funci贸n que retorna un error.

function createStudent({
    name = requiredParam("name")
    email = requiredParam("email"),
    age,
    aprrovedCourses = [],
    learningPaths = [],
    socialMedia,
} = {})

tira error cuando no estamos eenviando ninguna propiedad name o email.

Me falt贸 el 鈥淔acebook es undefined porque 隆驴Qui茅n tiene facebook?!鈥 del profee

Puedes tambi茅n crear una fabrica de instancias de prototipos con esta funci贸n ejemplo:

function createNewCourse({name,school,score,lang,freeAcces}){

    return new Courses({

        name,
        school,
        score,
        lang,
        freeAcces
    })
}

Like si te gustan los frijoles tanto como a juan!! 馃槀馃槅

RORO patter

Es un patr贸n de c贸digo en el que se env铆a como par谩metro a una funci贸n un objeto para devolver otro objeto, y el beneficio de esto principalmente es:

  1. Enviar par谩metros de forma m谩s descriptiva
  2. Ignorar el orden en el que deben ser colocados los par谩metros

Factory pattern y RORO

function requiredParam(param) {
  throw new Error(`Missing required parameter: ${param}`);
}

function createStudent({
  name = requiredParam('name'), //Mostar谩 error si est谩 vac铆o
  email = requiredParam('email'),
  age,
  twitter,
  facebook,
  instagram,
  approvedCourses = [], //valor por defecto
  learningPaths = [], //valor por defecto
} = {} /*Por defecto es un objeto vac铆o*/ ) {
  return {
    name,
    email,
    age,
    approvedCourses,
    learningPaths,
    socialMedia: {
      twitter,
      facebook,
      instagram
    },
  };
}

const juan = createStudent({
  name: 'Juan',
  email: '[email protected]',
  age: 20,
  twitter: '@fjuandc',
})

se pueden escuchar carros de formula 1 en el minuto 10:38

RORO = Recibir un Objecto, y Retornar otro Objecto.
Nos ayudan a crear moldes de objeto, pero no a partir de objetos literales, sino con funciones:

function requiredParams(param) {
  throw new Error(param + ": es un par谩metro requerido")
};

function createStudent({
  name = requiredParams("name"),
  age = requiredParams("age"),
  email,
  twitter,
  instagram,
  github,
  approvedCourses = [],
  learningPaths =[],
} = {}) {
  return {
    name,
    email,
    age,
    socialMedia: {
      twitter,
      instagram,
      github
    },
    approvedCourses,
    learningPaths,
  }
};

const felipe = createStudent({
  name: "Felipe",
  email: "[email protected]",
  age: 28,
  github: 'afelipelds',
});

Lo que est谩 haciendo el profe en la funci贸n createStudent, se llama destructuring, que en t茅rminos generales lo que hace es una especie de desempaquetado de las propiedades de objetos o arrays:

entonces en vez de 茅l hacer esto:

function createStudent(estudent) {
	return {
		name: student.name,
		age: student.age
		...
	}
}

lo que hace es un destructuring ese objeto student:

function createStudent({name, age, ... }) {
	return {
		name,
		age
		...
	}
}

Un enlace si quieren profundizar m谩s:

Destructuring assignment

Creemos una funci贸n que crear谩 objetos:

-Recibe como parametro un objeto para que no importe el orden en que se env铆an las propiedades

-Igualamos el parametro a un objeto vac铆o para que no exista error en caso de que no enviemos argumentos al llamar la funci贸n.

function createStudent({
  name, 
  email, 
  age,
  twitter,
  instagram,
  facebook,
  approvedCourses = [],
  learningPaths = [],
} = {})

-Retornamos un objeto con todas las propiedades enviadas (las propiedades no enviadas seran undefined)

{
  return {
    name,
    email,
    age,
    approvedCourses,
    learningPaths,
    socialMedia: {
      twitter,
      instagram,
      facebook,
    },
  };
}

-Pero si vamos a necesitar propiedades obligatorias, por esto, cuando no se envien vamos a lanzar un error

function requiredParam(param) {
  throw new Error(param + " es obligatorio");
}
function createStudent({
  name = requiredParam("name"),
  email = requiredParam("email"),
}={})

Espectacular revisar lo de RORO a帽adiendo los par谩metros por defecto.

Me gustan mas las explicaciones del profesor Nicolas, mucho mas claro al usar objetos mas 鈥渞eales鈥, es decir

Edificio{
	apartamento101{
		tipoApto{
			apto: suite
		},
		familiaRamirez{
			ana{
				genero: femenino,
				nombreCompleto: Ana Ramirez,
				edad: 30
			},
			sergio{
				genero: masculino,
				nombreCompleto: Sergio Ramirez,
				edad: 32
			},
		}
	},
	apartamento201{
		...
	}

en vez de

{a:b, {juanito: juan no esjuan}
Gracias por existir RORRO PIRRORO鉂わ笍鉂わ笍鉂わ笍

Para crear una f谩brica de objetos se siguen estos pasos:

  1. Se crea una funci贸n la cual debe recibir por par谩metro un objeto desestructurado (La ventaja de esto es que, al ejecutar la funci贸n, el argumento debe ser un objeto. De tal manera no se debe recordar el orden de los par谩metros para poder enviar los argumentos.) y a su vez dicho par谩metro debe ser por defecto un objeto vac铆o. Esto 煤ltimo impide que se generen errores al momento de hacer la ejecuci贸n de la funci贸n sin ning煤n argumento porque no se puede desestructurar las propiedades del argumento que, en este caso, tendr铆a valor 鈥渦ndefined鈥.

  2. La funci贸n debe retornar el par谩metro, es decir, el objeto desestructurado.

  3. Exterior a la funci贸n, se asigna a una variable la ejecuci贸n de la funci贸n con el argumento (un objeto) que se quiere enviar. En este punto el objeto se crea.

  4. Adicionalmente se puede restringir que algunas propiedades del objeto, que es par谩metro en la funci贸n, puedan aceptar valores indefinidos asignando a dichas propiedades valores por defecto (como si un par谩metro por defecto se tratase) una funci贸n externa que cree un error y detenga la ejecuci贸n del c贸digo utilizando la instrucci贸n throw.

Wow鈥! requiredParam

De verdad este curso es uno de los mejores de Platzi.

Increible Juan!

En esta clase a comparaci贸n de la anterior aprendimos a crear objetos haciendo uso de Factory Pattern y el patr贸n Roro

Una forma m谩s sencilla de crear errores, o cualquier otro tipo de respuesta dependiendo del caso de uso, si queremos que una variable sea obligatoriamente tomada en cuenta, es utilizar el operador de fusi贸n nulo o nullish coalescing:
.
Este operador funciona como un OR, con la diferencia de que devolver谩 el segundo valor 煤nicamente si el primero es un null o un undefined. Se utiliza ?? para representarlo:

const foo = null ?? 'default string';
console.log(foo);
// expected output: "default string"

const baz = 0 ?? 42;
console.log(baz);
// expected output: 0

Pueden leer m谩s al respecto en esta documentaci贸n en ingl茅s o en esta documentaci贸n en espa帽ol, en la parte de Operadores l贸gicos
.
En ese orden de ideas, para generar un error utilizando el c贸digo de la clase, basta con colocar esta operaci贸n dentro de la funci贸n createStudent() en las propiedades que queramos hacer obligatorias de llenar. Yo lo hice con con name e email para que sean obligatorios, pero tambi茅n lo us茅 en approvedCourses y learningPaths para que muestre una respuesta m谩s amigable que un arreglo vac铆o o un undefined , quedando de la siguiente manera:

function createStudent({
    name,
    age,
    email,
    twitter,
    facebook,
    instagram,
    approvedCourses,
    learningPaths
}) {

    return {
        name: name ?? console.error('Necesitas proporcionar tu nombre'),
        age,
        email: email ?? console.error('Necesitas proporcionar un email'),
        approvedCourses: approvedCourses ?? 'No tienes cursos aprovados',
        learningPaths: learningPaths ?? 'No haz elegido rutas de aprendizaje',
        socialMedia: {
            twitter,
            instagram,
            facebook,
        }
    };
}

La funci贸n requiredParam es una funci贸n auxiliar que se utiliza para asegurarse de que ciertos par谩metros sean proporcionados al llamar a otra funci贸n. Su prop贸sito es lanzar un error si un par谩metro requerido no se pasa o se pasa como undefined.
.
En el c贸digo que proporcionaste, la funci贸n requiredParam se utiliza en la funci贸n createStudent para los par谩metros name y email. Estos par谩metros se definen utilizando la sintaxis de desestructuraci贸n de objetos y se les asigna el valor de requiredParam("name") y requiredParam("email") respectivamente.
.
Cuando se llama a la funci贸n createStudent, los valores de name y email deben ser proporcionados como argumentos. Si alguno de estos argumentos no se pasa o se pasa como undefined, la funci贸n requiredParam lanzar谩 un error. El mensaje de error especificado en la funci贸n requiredParam indica qu茅 par谩metro es obligatorio.
.
Por ejemplo, si se llama a la funci贸n createStudent de la siguiente manera:

createStudent({ name: "John Doe" });

Se lanzar谩 un error con el mensaje 鈥渆mail es obligatorio鈥, porque el par谩metro email no se proporcion贸.
.
En resumen, la funci贸n requiredParam es una forma de asegurarse de que se proporcionen todos los par谩metros requeridos al llamar a una funci贸n y de lanzar un error si alguno de ellos falta. Esto ayuda a garantizar que la funci贸n se llame con los argumentos adecuados y evita errores o resultados inesperados en el c贸digo.

A continuaci贸n, te explicar茅 brevemente el Factory Pattern (patr贸n de f谩brica) y el concepto de RORO (Receive One, Return One) en JavaScript, y te proporcionar茅 un ejemplo pr谩ctico para cada uno de ellos.
.

  1. Factory Pattern (Patr贸n de f谩brica):
    El Factory Pattern es un patr贸n de dise帽o que se utiliza en programaci贸n para crear objetos. Proporciona una interfaz para crear objetos, pero delega la responsabilidad de qu茅 clase concreta instanciar al propio m茅todo de f谩brica. Esto permite desacoplar el c贸digo que utiliza los objetos de la forma en que se crean.
    .
    Ejemplo pr谩ctico:
    Supongamos que est谩s desarrollando una aplicaci贸n de gesti贸n de empleados. Puedes utilizar el Factory Pattern para crear objetos de diferentes tipos de empleados, como 鈥淒esarrollador鈥, 鈥淒ise帽ador鈥 o 鈥淕erente鈥. Aqu铆 tienes un ejemplo en JavaScript:
// Definici贸n de la clase Employee
class Employee {
  constructor(name, role) {
    this.name = name;
    this.role = role;
  }

  sayRole() {
    console.log(`Soy un ${this.role}`);
  }
}

// Definici贸n de la clase Factory
class EmployeeFactory {
  createEmployee(name, role) {
    return new Employee(name, role);
  }
}

// Uso del Factory para crear objetos de empleado
const factory = new EmployeeFactory();
const developer = factory.createEmployee("John Doe", "Desarrollador");
const designer = factory.createEmployee("Jane Smith", "Dise帽ador");

developer.sayRole(); // Output: Soy un Desarrollador
designer.sayRole(); // Output: Soy un Dise帽ador

En este ejemplo, el Factory (EmployeeFactory) se encarga de crear objetos de la clase Employee seg煤n los par谩metros proporcionados. Esto permite crear diferentes tipos de empleados sin que el c贸digo que utiliza los objetos tenga que preocuparse por la l贸gica de creaci贸n.
.

  1. RORO (Receive One, Return One):
    El concepto RORO es una convenci贸n en JavaScript que se utiliza para indicar que una funci贸n recibe un solo argumento y devuelve un solo valor. Ayuda a mejorar la legibilidad y el entendimiento del c贸digo, ya que es m谩s f谩cil comprender la entrada y salida de la funci贸n.

.
Ejemplo pr谩ctico:
Supongamos que tienes una funci贸n que toma un n煤mero como argumento y devuelve su cuadrado. Puedes aplicar el concepto RORO de la siguiente manera:

function square(number) {
  return number * number;
}

const result = square(5);
console.log(result); // Output: 25

.
En este ejemplo, la funci贸n square recibe un argumento (number) y devuelve el resultado del n煤mero al cuadrado. Al aplicar el concepto RORO, queda claro que la funci贸n toma un solo valor y devuelve otro valor, lo que facilita su comprensi贸n.

Espero que estos ejemplos pr谩cticos te ayuden a entender el Factory Pattern y el concepto RORO en JavaScript. Si tienes alguna otra pregunta, no dudes en hacerla.

Mi resumen:

/*-----------------Creaci贸n de objetos usando funciones-------------------*/

function createStudent({
    name,
    age
} = {}) { //define que si no se env铆a nada por argumento, entonces se crear谩 un objeto vaci贸, evitando que salga un error
    return {
        name,
        age
    }
}

const rica = createStudent();
console.log(rica); //{ name: undefined, age: undefined }

//Si es que se desea si o si pasar un dato obligatorio, se puede crear un funci贸n que retorne error

function requiredParam(param) { // 馃憟馃憟
    throw new Error(param + " es obligatorio"); // throw new Error es la forma de disparar errores en JS
}

//Entonces esta funci贸n se puede pasar por valor de una propiedad

function createStudent2({
    name,
    age = requiredParam("age")
} = {}) { //en este caso ya no servir铆a porque se tiene que mandar un valor obligatorio
    return {
        name,
        age
    }
}

const terry = createStudent2(); //Error: age es obligatorio
const luis = createStudent2({age:12});
console.log(luis); //{ name: undefined, age: 12 }