Cómo empezar a escribir Código ‘Complejo’

Este es un post sobre cómo pensar en el código que escribes. Todo lo contenido en este documento es mi opinión y siempre debe considerar la validez de mis opiniones comparándolas con otras mejores. El lenguaje que usaré es Javascript. Un requisito previo para entender este artículo es conocer Javascript intermedio y estar familiarizado con algunos conceptos orientados a objetos. Este post está inspirado en el capítulo 9 del excelente libro de Cristina Lopes “Ejercicios en estilo de programación”.

Un patrón muy común en el código es—

  1. Definir un objeto simple
var store_item = {
name : 'wonderball'
}

2. Luego, para que esté listo para mostrarse en una página web, ejecutamos cada propiedad a través de algunas funciones.

addExclamationPoint(store_item);
capitalizeName(store_item);function addExclamationPoint(item) {
item.name = item.name + '!';
}function capitalizeName(item) {
// some code to capitalize item.name, cut out for brevity.
}

Y así es como a menudo obtenemos los datos listos para mostrarse. Ahora que nuestro store_item tiene un nombre en mayúscula y un signo de exclamación, podemos mostrarlo en nuestra página web sin problema. Si hay una tercera cosa que necesitamos hacer, simplemente escribiríamos una tercera función para transformar los datos y pasaríamos el elemento como de costumbre.

El patrón de imagen más grande que hemos creado aquí es:

Hay un par de términos extraños para este tipo de programación, tales como ‘procesal’, o ‘imperativo’, pero yo diría que es un término diferente: ‘simple’. Es una programación muy simple. Es el tipo de programación que todos aprenden primero. Para programas de pequeña escala, es absolutamente la mejor manera de programar, porque los humanos son buenos para seguir de 1 a 10 pasos lógicos bastante bien.

Cuando el programa es lo suficientemente grande (más de 10 transformaciones antes de que se muestren los datos), o cuando una función está modificando muchos objetos de datos (más de 2), o tenemos muchas sentencias IF que causan lógica de ramificación, esta programación “simple” se convierte en “un desastre”.

Casi todos los proyectos o piezas de código se complican. La mayor parte de la programación es en realidad codificadores que buscan formas de evitar hacer un desastre, no soluciones al problema real de mostrar los datos. El trabajo de programación consiste en aprender a escribir código de tal manera que podamos aplicar 100 de transformaciones en 100 de piezas de datos y hacer que “no sea un desastre”.

Ahora, déjame presentarte un gran cambio en el patrón anterior, y considera que lo que estoy a punto de mostrarte es el primer paso para convertirte en un codificador más avanzado porque te libera de la codificación “simple”. Te presenta nuevas formas de pensar sobre cómo hacer algo simple como modificar algunos datos para una página web. El objeto ahora tendrá su propia función llamada ‘bind’, y esa función será responsable de transformar los datos.

var store_item = {
name: 'wonderball',
bind: function(func) {
this.name = func(this.name);
return this;
}
}// Here are two functions I'll use to transform the store_item.name, each one now just takes a name and modifies it, neither function has any clue what properties it's changing in store_item anymore.function capitalize(name) {
return name.replace(/\w\S*/g, function(txt) {
return txt.charAt(0).toUpperCase() +
txt.substr(1).toLowerCase();
});
}function addExclamationPoint(name) {
return name + '!';
}store_item.bind(addExclamationPoint).bind(capitalize);

Esta solución se comporta exactamente como el código “simple” original anterior, pero parece más complejo, ¿por qué? Porque para la tarea simple que tenemos, es una exageración, pero ¿cuáles son las ventajas y desventajas de esta complejidad?

Para responder a eso, hablemos de lo que es diferente:

  1. Tenemos esta loca, extraña función ‘bind’, que toma como argumento, no un nuevo valor para el nombre,sino otra función, ¿qué dices ahora?
  2. las funciones capitalizar y addExclamationPoint son diferentes, ahora no llaman item.name directamente más.
  3. Ya no establecemos el nombre con un’=’, en su lugar usamos este extraño store_item.bind (nombre_función), sintaxis en su lugar.

Con estas tres diferencias, ahora tenemos que preguntarnos, ¿es mejor este cambio? Tal vez no si el proyecto sigue siendo tan pequeño. Tal vez sí, si el proyecto se hace mucho más grande.

El cambio de clave es que el objeto store_item ahora es responsable de manejar su estado a través de la función bind. Por supuesto, si quisieras, podrías alterar directamente store_item.name, pero el objeto prácticamente grita: “¡Oye, usa mi función de enlace para cambiarme!”.

Pero ahora es fácil ver un patrón en el que varios store_items administran su propio estado con el suyo propio .función de enlace:

// Three store items, each one with a different state.store_item1.bind(addExclamationPoint).bind(capitalize); //Wonderball!store_item2.bind(capitalize);
//Wonderballstore_item3.bind(addExclamationPoint);
//wonderball!

Podemos hacer 100 store_item y administrar sus estados con bastante facilidad. Todo lo que tenemos que hacer es escribir una función que solo tiene un valor de retorno y usar el de nuestro objeto .función de enlace.

La magia de este patrón está en la función bind, así que exploremos eso un poco más ahora.

// 1. First define the function, and have it take as an argument another function. Taking a function as an argument, instead of data is the core change here. bind: function(func) { // 2. This second line is the secret sauce, it will run the function you passed in with 'this.name' as an argument, and then assign whatever value is returned to this.name. Mull this over. this.name = func(this.name);// 3. Finally, return 'this'. You don't have to have this step in here, but returning 'this' is what allows .bind chainging to happen (.e.g. doing .bind().bind() vs .bind(); .bind();) return this;
}

Así que ahí lo tienes, hemos hecho nuestro código más complejo, pero ahora tenemos algunos beneficios nuevos:

  1. Un objeto ahora modifica su propio estado, y puede hacerlo significativamente en una sola línea.
  2. Las funciones que hemos escrito son más puras, no modifican las propiedades de un objeto como en el ejemplo anterior, solo toman una entrada y devuelven una salida.
  3. Sabemos que cuando modificamos el estado de un objeto, las funciones que usamos probablemente no modificarán el estado de ningún otro objeto accidentalmente

, pero también tenemos algunas desventajas:

  1. Su código es definitivamente menos intuitivo para un recién llegado ahora.
  2. Para un sitio pequeño, este código es demasiado complejo.

Entonces, ¿cuál es el juicio final, es así mejor? Peor? Más confuso? (Al principio, sí. Todas estas preguntas están abiertas, pero puedo decir una cosa con seguridad, considerar y comprender patrones como este es parte del aprendizaje de Javascript y el crecimiento como codificador. El uso continuo de la forma “simple” de codificar para resolver problemas se vuelve insostenible después de un tiempo. Si se toma el tiempo para aprender formas más “complejas” de hacer las cosas, suceden muchas cosas geniales: su capacidad de pensar lateralmente se abre, puede leer más tipos de código diversos y aumenta las formas en que puede pensar para resolver problemas. Tal vez ese sea el verdadero beneficio de aprender este y otros patrones.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.