Antipatrones que debe evitar en su código

Todo desarrollador quiere escribir código estructurado, simplemente planificado y bien comentado. Incluso hay una gran cantidad de patrones de diseño que nos brindan reglas claras a seguir y un marco a tener en cuenta.

Pero aún podemos encontrar anti-patrones en software que fue escrito hace algún tiempo o fue escrito demasiado rápido.

Un truco básico inofensivo para resolver un problema rápidamente puede sentar un precedente en su base de código. Se puede copiar en varios lugares y convertirse en un antipatrón que debe abordar.

Entonces, ¿qué es un anti-patrón?

En software, anti-patrón es un término que describe cómo NO resolver problemas recurrentes en su código. Los antipatrones se consideran un mal diseño de software y, por lo general, son soluciones poco efectivas u oscuras.  

Por lo general, también agregan "deuda técnica", que es un código que debe regresar y corregir correctamente más tarde.

Los seis anti-patrones que discutiré en este artículo son el Código Espagueti , el Martillo Dorado , el Ancla de Barco , el Código Muerto , la Proliferación del Código y el Objeto Dios .

Código de espagueti

Spaghetti Code es el anti-patrón más conocido. Es un código con poca o ninguna estructura.

Nada está modularizado. Hay archivos aleatorios esparcidos en directorios aleatorios. Todo el flujo es difícil de seguir y está completamente enredado (como espaguetis).

Normalmente, este es un problema en el que alguien no ha pensado detenidamente el flujo de su programa de antemano y acaba de empezar a codificar.

¡¿Qué hace?! No puedo seguir esto

image.png

Esto no solo es una pesadilla de mantenimiento, sino que hace que sea casi imposible agregar nuevas funciones.

Constantemente romperá las cosas, no comprenderá el alcance de sus cambios o dará estimaciones precisas para su trabajo, ya que es imposible prever los innumerables problemas que surgen al hacer tal arqueología / conjeturas.

Puedes leer más aquí sobre el anti-patrón Spaghetti Code .

Martillo dorado

"Supongo que es tentador, si la única herramienta que tienes es un martillo, tratar todo como si fuera un clavo". Abraham Maslow

Imagínese un escenario conmigo: su equipo de desarrollo es muy, muy competente en la nueva arquitectura de Hammer. Ha funcionado fantásticamente para todos sus problemas anteriores. Eres el equipo de arquitectura de Hammer líder en el mundo.

Pero ahora, de alguna manera, todo siempre termina usando esta arquitectura. ¿Un tornillo de cabeza plana? Martillo. Tornillo de cabeza Phillips? Martillo. ¿Necesitas una llave Allen? No, no lo hagas, martillalo.

Empieza a aplicar un enfoque arquitectónico que no se ajusta del todo a lo que necesita, pero hace el trabajo. Depende demasiado de un patrón y necesita aprender la mejor herramienta para el mejor trabajo.

Todo su programa podría terminar teniendo un serio impacto en el rendimiento porque está tratando de embestir un cuadrado en forma de círculo. Sabe que se necesita el doble de tiempo para codificar y ejecutar un programa usando la arquitectura de martillo para este problema, pero es más fácil y es con lo que se siente cómodo.

Tampoco es muy predecible. Los diferentes lenguajes tienen soluciones comunes a los problemas que enfrentan y sus propios estándares. No puede aplicar todas las reglas que le funcionaron bien en un idioma a otro, sin problemas.

No descuides el aprendizaje constante en tu carrera. Elija el idioma adecuado para su problema. Piense en la arquitectura y saque su zona de confort. Investigue e investigue nuevas herramientas y nuevas formas de abordar los problemas que enfrenta.

Puedes leer más aquí sobre el anti-patrón Golden Hammer .

Ancla de barco

El anti-patrón Boat Anchor es donde los programadores dejan código en la base de código porque podrían necesitarlo más adelante.

Codificaron algo ligeramente fuera de especificación y aún no es necesario, pero están seguros de que lo harán el próximo mes. Entonces no quieren borrarlo. Envíelo a producción y más tarde, cuando lo necesiten, podrán hacerlo funcionar rápidamente.

Pero esto causa pesadillas de mantenimiento en el código base que contiene todo ese código obsoleto. El gran problema es que sus colegas tendrán dificultades para determinar qué código es obsoleto y no cambia el flujo, en comparación con el código que sí lo hace.

Imagine que está en una solución urgente y está tratando desesperadamente de averiguar qué es responsable de enviar los detalles de la tarjeta de los clientes a la API para retirar fondos de su banco. Podría perder el tiempo leyendo y depurando código obsoleto, sin darse cuenta de que ni siquiera está en el lugar correcto en la base de código.

El problema final es que el código obsoleto alarga el tiempo de compilación y puede confundir el código funcional con el obsoleto. Incluso podría comenzar a "encenderlo" inadvertidamente en producción.

Ahora probablemente pueda ver por qué se llama antipatrón de ancla de barco: es pesado de transportar (agrega deuda técnica) pero no hace nada (literalmente, el código no sirve para nada, no funciona).

Puedes leer más aquí sobre el anti-patrón de ancla de barco .

Código muerto

¿Alguna vez ha tenido que mirar el código escrito por alguien que ya no trabaja en su empresa? Hay una función que no parece que esté haciendo nada. ¡Pero se llama desde todas partes! Preguntas a tu alrededor y nadie más está seguro de lo que está haciendo, pero todos están demasiado preocupados como para eliminarlo.

A veces puedes ver lo que está haciendo, pero falta el contexto. Puede leer y comprender el flujo, pero ¿por qué? Ya no parece que necesitemos llegar a ese punto final. La respuesta es siempre la misma respuesta para cada usuario diferente.

This is commonly described as the Dead code anti-pattern. When you can't see what is "actual" code necessary to the flow and successful execution of your program, versus what was only needed 3 years ago, and not now.

This particular anti-pattern is more common in proof on concept or research code that ended up in production.

One time at a tech meet up I met a guy who had this exact problem. He had tons of dead code, which he knew was dead, and lots he suspected was dead. But he could not get permission from management to ever remove all the dead code.

He referred to his approach as Monkey testing, where he started to comment out and turn off things to see what blew up in production. Maybe a little too risky!

If you don't fancy Monkey testing your production app, try to frame technical debt to management as "technical risk" to better explain why you think it's so important to tidy up.

Or even write down everything your particular module/section does you want to re-write, and take an iterative approach to remove piece by piece the dead code. Checking every time you haven't broken anything.

You don't have to drop a huge rewrite with thousands of changes. But you will either understand why it's so crucial and document why it's needed, or delete the dead code as you desired.

You can read more here about the Dead code anti-pattern.

Proliferation of Code

Objects or modules regularly communicate with others. If you have a clean, modularised codebase you often will need to call into other separate modules and call new functions.

The Proliferation of Code anti-pattern is when you have objects in your codebase that only exist to invoke another more important object. Its purpose is only as a middleman.

This adds an unnecessary level of abstraction (adds something that you have to remember) and serves no purpose, other than to confuse people who need to understand the flow and execution of your codebase.

A simple fix here is to just remove it. Move the responsibility of invoking the object you really want to the calling object.

You can read more here about the Proliferation of Code anti-pattern.

God Object

If everywhere in your codebase needs access to one object, it might be a God object.

God objects do too much. They are responsible for the user id, the transaction id, the customer's first and last name, the total sum of the transaction, the item/s the user is purchasing...you get the picture.

It is sometimes called the Swiss Army Knife anti-pattern because you only really need it to cut some twine, but it also can be a nail file, saw, pair of tweezers, scissors, bottle opener and a cork screw too.

In this instance you need to separate out and modularise your code better.

Programmers often compare this problem to asking for a banana, but receiving a gorilla holding a banana. You got what you asked for, but more than what you need.

The SOLID principles explicitly discuss this in object orientated languages, to help us model our software better (if you don't know what the SOLID principles are, you can read this article).

The S in the acronym stands for Single Responsibility - every class/module/function should have responsibility over one part of the system, not multiple.

You can see this problem over and over again, how about the below interface?

interface Animal { numOfLegs: string; weight: number; engine: string; model: string; sound: string; claws: boolean; wingspan: string; customerId: string; } 

Can you see by even just briefly scanning this interface that the responsibility of this is far too broad, and needs refactoring? Whatever implements this has the potential to be a God object.

How about this?

 interface Animal { numOfLegs: string; weight: number; sound: string; claws: boolean; } interface Car { engine: string; model: string; } interface Bird { wingspan: string; } interface Transaction { customerId: string; } 

Interface segregation will keep your code clear about where the responsibilities lie, and stop forcing classes that only need wingspan to also implement the engine, customerId and model  and so on.

Puede leer más aquí sobre el antipatrón del objeto Dios .

Conclusión

En cualquier base de código grande, existe un equilibrio constante entre la gestión de la deuda técnica, el inicio de un nuevo desarrollo y la gestión de una cola de errores para su producto.

Espero que este artículo le haya dado un ojo para detectar cuándo podría estar bajando por la madriguera de un anti-patrón, y algunas herramientas para resolverlo limpiamente.

Comparto mi escritura en Twitter si te gustó este artículo y quieres ver más.