Skip to content

Commit

Permalink
Translate "Goodbye, clean code" into Spanish (gaearon#577)
Browse files Browse the repository at this point in the history
* Translate 'Goodbye, clean code' to spanish.

* Apply suggestions.

* Improve translation for 'squishy humans'.
  • Loading branch information
Veuge authored and carburo committed Jan 16, 2020
1 parent c85cc4d commit e1bd353
Showing 1 changed file with 181 additions and 0 deletions.
181 changes: 181 additions & 0 deletions src/pages/goodbye-clean-code/index.es.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
---
title: 'Adios, Código Limpio'
date: '2020-01-11'
spoiler: Deja que el código limpio te guíe. Luego déjalo ir.
---

Era tarde en la noche.

Mi colega acababa de subir el código en el que había estado trabajando toda la semana. Estabamos trabajando en un editor de gráficos en canvas y ellos implementaron la capacidad de redimensionar las figuras, como rectángulos y óvalos, usando pequeños controles en sus bordes y arrastrándolos.

El código funcionaba.

Pero era repetitivo. Cada figura (como un rectángulo o un óvalo) tenía conjunto diferente de controles, y arrastrar cada control en direcciones diferentes modificaba la posición y tamaño de la figura de manera diferente. Si el usuario mantenía presionada la tecla Shift, también preservabamos las proporciones mientras redimensionabamos. Había mucha lógica matemática.

El código era algo así:

```jsx
let Rectangle = {
resizeTopLeft(position, size, preserveAspect, dx, dy) {
// 10 líneas repetitivas de operaciones matemáticas
},
resizeTopRight(position, size, preserveAspect, dx, dy) {
// 10 líneas repetitivas de operaciones matemáticas
},
resizeBottomLeft(position, size, preserveAspect, dx, dy) {
// 10 líneas repetitivas de operaciones matemáticas
},
resizeBottomRight(position, size, preserveAspect, dx, dy) {
// 10 líneas repetitivas de operaciones matemáticas
},
};

let Oval = {
resizeLeft(position, size, preserveAspect, dx, dy) {
// 10 líneas repetitivas de operaciones matemáticas
},
resizeRight(position, size, preserveAspect, dx, dy) {
// 10 líneas repetitivas de operaciones matemáticas
},
resizeTop(position, size, preserveAspect, dx, dy) {
// 10 líneas repetitivas de operaciones matemáticas
},
resizeBottom(position, size, preserveAspect, dx, dy) {
// 10 líneas repetitivas de operaciones matemáticas
},
};

let Header = {
resizeLeft(position, size, preserveAspect, dx, dy) {
// 10 líneas repetitivas de operaciones matemáticas
},
resizeRight(position, size, preserveAspect, dx, dy) {
// 10 líneas repetitivas de operaciones matemáticas
},
}

let TextBlock = {
resizeTopLeft(position, size, preserveAspect, dx, dy) {
// 10 líneas repetitivas de operaciones matemáticas
},
resizeTopRight(position, size, preserveAspect, dx, dy) {
// 10 líneas repetitivas de operaciones matemáticas
},
resizeBottomLeft(position, size, preserveAspect, dx, dy) {
// 10 líneas repetitivas de operaciones matemáticas
},
resizeBottomRight(position, size, preserveAspect, dx, dy) {
// 10 líneas repetitivas de operaciones matemáticas
},
};
```

Esas operaciones matemáticas repetidas me estaban molestando.

No era *limpio*.

La mayor parte de la repetición se daba entre direcciones similares. Por ejemplo, `Oval.resizeLeft()` tenia similitudes con `Header.resizeLeft()`. Esto se debía a que ambos se ocupaban de arrastrar el control del lado izquierdo.

La otra similitud se daba entre métodos para la misma figura. Por ejemplo, `Oval.resizeLeft()` tenía similitudes con los otros métodos de `Oval`. Esto porque todos ellos se ocupaban de los óvalos. También había duplicidad de código entre `Rectangle`, `Header` y `TextBlock` porque los `TextBlock` *eran* `Rectangle`.

Tenía una idea.

Podíamos *eliminar todo el código repetido* agrupándolo de esta manera:

```jsx
let Directions = {
top(...) {
// 5 líneas no repetidas de operaciones matemáticas
},
left(...) {
// 5 líneas no repetidas de operaciones matemáticas
},
bottom(...) {
// 5 líneas no repetidas de operaciones matemáticas
},
right(...) {
// 5 líneas no repetidas de operaciones matemáticas
},
};

let Shapes = {
Oval(...) {
// 5 líneas no repetidas de operaciones matemáticas
},
Rectangle(...) {
// 5 líneas no repetidas de operaciones matemáticas
},
}
```

y luego componiendo sus comportamientos:

```jsx
let {top, bottom, left, right} = Directions;

function createHandle(directions) {
// 20 líneas de código
}

let fourCorners = [
createHandle([top, left]),
createHandle([top, right]),
createHandle([bottom, left]),
createHandle([bottom, right]),
];
let fourSides = [
createHandle([top]),
createHandle([left]),
createHandle([right]),
createHandle([bottom]),
];
let twoSides = [
createHandle([left]),
createHandle([right]),
];

function createBox(shape, handles) {
// 20 líneas de código
}

let Rectangle = createBox(Shapes.Rectangle, fourCorners);
let Oval = createBox(Shapes.Oval, fourSides);
let Header = createBox(Shapes.Rectangle, twoSides);
let TextBox = createBox(Shapes.Rectangle, fourCorners);
```

¡El código ocupaba la mitad y la duplicación se había ido completamente! Entonces estaba *limpio*. Si queríamos cambiar el comportamiento para una dirección en particular, podíamos hacerlo en un solo lugar, en vez de actualizar todos los métodos que estaban duplicados.

Ya era tarde en la noche (me dejé llevar). Subí mis cambios de refactorización a master y me fuí a la cama, orgulloso de como pude desenredar el código desordenado de mi colega.

## La mañana siguiente

... no fue como esperaba.

Mi jefe me invitó a una reunión uno-a-uno donde cortésmente me pidieron que revirtiera mis cambios. Estaba atónito. ¡El código anterior era un desastre, y el mío era *limpio*!.

Cumplí a regañadientes, pero me tomó años darme cuenta de que tenían razón.

## Es una fase

Obsesionarse con el "código limpio" y eliminar toda duplicación es una fase por la que muchos de nosotros pasamos. Cuando no nos sentimos seguros de nuestro código, es tentador vincular nuestro sentido de autoestima y orgullo profesional a algo que se puede medir. Un conjunto de reglas de un linter, un esquema de nombres, una estructura de archivos, una falta de duplicación.

No puedes automatizar la eliminación de código repetido, pero se hace más fácil con la práctica. Usualmente puedes darte cuenta que hay más o menos de esto después de cada cambio. Como resultado, eliminar duplicación se siemte como mejorar alguna métrica objetiva del código. Peor, esto desordena con el sentido de identidad de las personas: *Soy el tipo de persona que escribe código limpio*. Es tan poderoso como cualquier otro tipo de autoengaño.

Una vez que aprendemos como crear [abstracciones](https://www.sandimetz.com/blog/2016/1/20/the-wrong-abstraction), es tentador dejarse llevar por esa habilidad y sacar abstracciones de la nada en cualquier momento que vemos código repetido. Despues de muchos años codificando, vemos repetición *en todos lados* -- y abstraer es nuestro nuevo superpoder. Si alguien nos dice que la abstracción es una *virtud*, le creemos. Y empezamos a juzgar a otros por no rendir culto a la "limpieza en el código".

Ahora veo como mi "refactorización" era un desastre por dos razones:

* Primero, no hablé con la persona que lo escribió. Reescribí el código y lo subí sin su aporte. Aunque era una mejora (cosa que ya no considero así), es una manera terrible de hacerlo. Un equipo de ingeniería sano está constantemente *construyendo confianza*. Reescribir el código de tu compañero de equipo sin una discusión previa es un gran golpe para su habilidad como equipo de colaborar efectivamente en una base de código.

* Segundo, nada es gratis. Mi código intercambiaba la habilidad de cambiar los requerimientos por menos duplicidad de código, y ese no era un buen intercambio. Por ejemplo, luego necesitamos muchos casos y comportamientos especiales para los diferentes controles en las diferentes figuras. Mi abstracción se hubiera convertido mucho más desordenado para lograr eso a la larga, mientras que la versión original "desordenada" pudo afrontar esos cambios de manera fácil.

¿Estoy diciendo que debemos escribir código "sucio"? No. Estoy sugiriendo que pensemos profundamente a que nos referimos cuando decimos "limpio" o "sucio". ¿Te da un sentimiento de revolución? ¿Correctitud? ¿Belleza? ¿Elegancia? ¿Qué tan seguro estás de que puedes darles un nombre a los resultados de ingeniería concretos correspondientes a esas cualidades? ¿Cómo afectan exactamente a la manera en la que el código está escrito y es [modificado](/optimized-for-change/)?

Estoy seguro que no pensaste profundamente acerca de estas cosas. Yo pensaba mucho acerca de como *lucía* el código -- pero no acerca de como *evolucionaba* con un equipo de simples humanos.

Codificar es un viaje. Piensa que tan lejos has llegado desde tu primera linea de código hasta donde estás ahora. Reconozco que fue una alegría ver por primera vez como extraer una función o refactorizar una clase puede hacer el código mas simple. Si te enorgulleces de tu oficio, es tentador perseguir la limpieza de código. Hazlo por un tiempo.

Pero no te quedes ahi. No seas un fanático del código limpio. El código limpio no es una meta. Es un intento de dar sentido a la inmensa complejidad de sistemas con los que lidiamos. Es un mecanismo de defensa cuando no estas seguro de como un cambio puede afectar una base de código pero necesitas guía en un mar de incognitas.

Deja que el código limpio te guíe. *Luego déjalo ir.*

0 comments on commit e1bd353

Please sign in to comment.