Puntos clave: Comprender la distinción entre patrones y anti-patrones está crucial en ingeniería de software. Los patrones ofrecen soluciones efectivas, aunque los anti-patrones pueden parecer beneficiosos, pero pueden llevar a resultados negativos.
- Los patrones de diseño incluyen conceptos como fábricas y metodologías ágiles.
- Los anti-patrones comunes surgen de buenas intenciones, pero resultan en ineficiencias, como el riesgo moral.
La jerga impregna la industria del desarrollo de software. Mejores prácticas. Artefactos. Expansión del alcance. Muchos de estos términos son tan comunes que se consideran sobreutilizados, y están fácil asumir que los entendemos porque parecen tan obvios. Aun así, a veces encontramos una nueva profundidad cuando los examinamos detenidamente. En esta entrada, reflexionemos sobre el "patrón" y su contraparte algo menos conocida, el "anti-patrón".
¿Qué son diseña patrones?
Todos sabemos qué patrones suelen son en el lenguaje común, pero para entender su importancia en la ingeniería de software es importante hablar primero de los algoritmos. Un algoritmo están simplemente una forma de realizar una tarea común, como ordenar una lista de elementos, almacenar datos para una recuperación eficiente o contar las ocurrencias de un elemento dentro de un conjunto de datos. Los algoritmos son uno de los conceptos más antiguos y fundamentales en ingeniería de software. De hecho, sobre el escritorio de este autor hay una copia de lo que muchos consideran una de las obras más fundamentales sobre el tema, Algoritmos fundamentales de Donald Knuth. La primera edición de este pequeño tomo de poco más de 600 páginas fue registrada por primera vez en 1968, hace 50 años. El texto sería casi irreconocible para un programador moderno, ya que enfatiza principalmente demostraciones basadas en cálculo de sus soluciones y sus únicos ejemplos de código son proporcionados en lenguajes oscuros y obsoletos como Algol o MIX Assembly. A pesar de esto, gran parte de lo que se cubría están sigue usándose hoy en día: listas unidas y doblemente enlazadas, árboles, recogida de basura, etc. Los detalles son a menudo enterrados en bibliotecas convenientes, pero los conceptos son los mismos. Estos algoritmos han permanecido como soluciones válidas a problemas comunes de ingeniería de software durante más de 5 décadas y son siguen funcionando. La discusión sobre patrones de diseño está incompleta sin profundizar en la importancia de los buenos principios de diseño. Lee más sobre principios sólidos de diseño.
Tipos de patrones
Un "patrón" puede considerarse una forma más general de algoritmo. Mientras que un algoritmo puede centrarse en una tarea de programación específica, un patrón puede considerar desafíos más allá de ese ámbito y en áreas como reducir las tasas de defectos, aumentar la mantenibilidad del código o permitir que grandes equipos trabajen juntos de forma más eficaz. Algunos patrones comunes incluyen:
- Fábricas – Una evolución de los primeros conceptos de programación orientada a objetos que eliminó la necesidad de que el creador de un objeto supiera todo sobre él de antemano. Una aplicación de diagrama de flujo podría soportar bibliotecas extensibles de plantillas centrándose en crear y organizar "formas", permitiendo que las plantillas gestionen los detalles de crear un simple cuadrado frente a un icono complejo de router de red.
- Pub/Sub – Un mecanismo para "desacoplar" aplicaciones. En lugar de que un emisor envíe mensajes directamente a un receptor, este "publica" los mensajes en un tema o cola. Uno o más receptores pueden "suscribirse" para recibir esos mensajes, y la cola de mensajes gestiona detalles como errores de transmisión o reenvío de mensajes. Esto simplifica tanto las aplicaciones de envío como las de receptor.
- Criptografía de clave pública – Un mecanismo mediante el cual dos partes pueden comunicarse de forma segura y sin interceptación, pero sin necesidad de predisponer un intercambio de claves secretas de cifrado. Cada parte mantiene un par de claves (públicas y privadas), y la clave pública a menudo puede obtenerse según sea necesario en lugar de intercambiarse previamente.
- Ágil – Una filosofía que encapsula un conjunto de principios rectores para el desarrollo de software que enfatizan la satisfacción del cliente, aceptan la necesidad de flexibilidad y colaboración, y promueven la adopción de prácticas de desarrollo simples y sostenibles.
Estos son solo cuatro de los muchos patrones comunes en la industria, y aun en esta mezcla podemos Ve cómo van desde los más técnicos hasta puntos más amplios y orientados a procesos. Las fábricas son un patrón muy orientado al código, mientras que las están de carácter más arquitectónico. Y aunque la criptografía de clave pública tiene amplias implicaciones, las bibliotecas que apoyan sus operaciones son disponibles para casi todos los lenguajes de programación comunes hoy en utiliza día, lo que hace que sea generalmente sencillo de implementar.
Concepción errónea de los patrones ágiles
En el otro extremo, "Ágil" sigue siendo algo esquivo: simultáneamente un punto de unión y un instrumento de división entre desarrolladores, gestores de proyectos y otros grupos de interés sobre qué significa exactamente y cómo debe implementarse. Es un gran ejemplo de un término sobreutilizado pero poco comprendido. Ver los términos "Waterfall" o "Stand ups" en la misma frase que "Ágil" casi siempre están un ejemplo de mal uso. Ágil están una filosofía, no una metodología de desarrollo de software, por lo que no puede compararse directamente con Waterfall, ni detalla directamente componentes de proceso como los stand-ups. (Esos son un componente de Scrum, una metodología que implementa principios Ágil, pero no representa a Agile en sí.) Sean estrechos o amplios, técnicos o orientados a procesos, un buen conocimiento práctico de estos patrones está un componente esencial en la caja de herramientas de un tecnólogo.
¿Qué es un anti-patrón?
Si un "patrón" están simplemente una solución conocida para funcionar a un problema común de ingeniería de software, ¿no sería un "anti-patrón" simplemente lo contrario? ¿Una metodología de desarrollo no Ágil o una aplicación estrechamente acoplada? En realidad, los anti-patrones no solo incorporan el concepto de no hacer lo correcto, sino que también incluyen un conjunto de elecciones que parecen correctas a simple vista, pero que a la larga conducen a problemas. Wikipedia define el significado de "Anti-patrón" de la siguiente manera:
"Un anti-patrón están una respuesta común a un problema recurrente que normalmente están ineficaz y que corre el riesgo de ser altamente contraproducente."
Fíjate en la referencia a "una respuesta común". Los anti-patrones no son errores ocasionales, son comunes y casi siempre Comienza con buenas intenciones. Como ocurre con los patrones normales, los anti-patrones pueden ser amplios o muy específicos, y cuando se trata de lenguajes de programación y frameworks, puede haber literalmente cientos a considerar. Aquí son solo algunos de los ejemplos anti-patrones favoritos y de alto nivel de este autor.
Desafíos de programación en pizarra en entrevistas de software
David Hansson, creador de Ruby on Rails y fundador y CTO de Basecamp, tuiteó una vez: "Hola, me llamo están David. No sería capaz de escribir ordenación de burbujas en una pizarra. Busco código en internet todo el tiempo. No hago acertijos." El anti-patrón aquí están evaluar métricas incorrectas durante una entrevista, como cuando una tarea típica es "Añadir búsqueda de código postal durante el registro", pero las preguntas de entrevista suenan a "Ordena este array en pseudocódigo usando conceptos de programación funcional." ¿Recuerdas el aspecto de "buenas intenciones" de los anti-patrones? Parece que estamos son evaluando al candidato sobre un principio valioso: el conocimiento de los fundamentos. Sin embargo, la programación están a menudo una práctica implacablemente pragmática, y este enfoque en el conocimiento teórico por encima de las habilidades prácticas y la experiencia puede llevarnos a elegir un candidato que cumpla con nuestros ideales culturales, pero careza de las habilidades reales necesarias para tener éxito en el puesto. Dicho de otro modo: si StackOverflow será un recurso habitual utilizado por el desarrollador en el puesto, debería estar disponible (y utilizado) durante la entrevista. También pueden merecer la pena explorar tareas de deberes y desafíos de programación en pareja. Todos los patrones y anti-patrones tienen excepciones válidas. Un desarrollador cuyo trabajo será Haz librerías de algoritmos para que otros los utilicen puede muy bien necesitar conocer el cálculo detrás de un mecanismo. El error aquí están aplicar esta expectativa universalmente, incluso a desarrolladores que no lo harán.
Riesgo moral
En contextos filosóficos, el riesgo moral están la separación de individuos de las consecuencias de sus decisiones. Esto parece un comportamiento obvio a evitar, pero este anti-patrón están la causa raíz de muchas ineficiencias de SDLC. considera el proceso tradicional de QA, en el que los "tickets" son abordados por los desarrolladores y luego pasados a QA para revisión antes de ser implementados. Aquí son dos problemas. Primero, las proporciones de personal casi nunca son "1 desarrollador por 1 analista de QA", e incluso un puñado de desarrolladores puede superar fácilmente la capacidad del equipo de QA. Segundo, esto aísla a los desarrolladores de las consecuencias de sus errores al hacer que sea responsabilidad de otra persona encontrarlos antes de que son liberados, un riesgo moral. Los efectos de este anti-patrón pueden ser sutiles: si el equipo de QA es eficaz, puede que no conduzca directamente a una menor calidad de resultados. Están más probables que se manifiesto en otras áreas, como quejas sobre la precisión de estimaciones y los objetivos fallidos. La calidad y la precisión en estimaciones sufren porque los desarrolladores se centran instintivamente en "pasar por QA" en lugar de lanzar software de alta calidad. Incluso con una tasa de defectos modesta del 20-30% (una cifra que incluso podría ser optimista en muchas organizaciones), la rotación que esto produce puede afectar significativamente a la productividad del equipo. A menudo surgen anti-patrones adicionales en el intento de resolver el problema. En Scrum, puede ser tentador Haz los sprints más largos o mantenerlos abiertos. Pero un sprint está pensado para ser una medida de tiempo, no una medida de salida. Este acto invierte esa naturaleza, lo que destruye el valor de otras herramientas como las métricas de "velocidad" que son basadas en ella. También es común Ve reuniones de planificación de sprints más largas o pre-planificación para revisar los tickets en profundidad. Pero esto intenta convertir un proceso instintivo en uno científico, olvidando que el propósito de implementar una metodología como Scrum era reconocer esta imposibilidad desde el principio. Dos patrones que a menudo son efectivos para resolver este problema incluyen:
- Adoptar una cultura de mejora continua: "envíalo cuando es mejor, no cuando es lo correcto." (Ve también "Puliendo la bala de cañón" más abajo). Los desarrolladores animados y empoderados para hacer esto pueden Haz mejores decisiones sobre cómo afrontar sus tareas y también experimentar una sensación más tangible de logro personal.
- Haz que los desarrolladores sean responsables de su trabajo hasta los despliegues en producción. Facebook, Google y otros gigantes de la industria han reportado éxito con este enfoque.
Pulido de la bala de cañón
A veces también conocido como "chapado en oro" o "hervir el océano", intentar enviar productos perfectos suele aumentar significativamente los plazos y costes de los proyectos sin aumentar realmente el valor entregado. Un anti-patrón estrechamente relacionado están el "ticket zombi", la placa en las paredes arteriales del Backlog. Los tickets zombie nunca son una prioridad lo suficientemente alta como para Obtén limpiados, pero son nunca se cerran por miedo a perder el registro documental de la tarea. El problema de ambos hábitos están que las métricas que los respaldan son fantasmas. Las características no enviadas no tienen ningún valor para los clientes, y las tareas que no causan suficiente dolor como para convertirse en prioridades pueden no merecer la pena abordar. Casi siempre están mejor centrar los recursos disponibles en ofrecer regularmente nuevas funciones valiosas en lugar de mirar constantemente hacia atrás en pequeños problemas que afectan a muy pocos usuarios. El equivalente "patrón" aquí están el producto mínimamente viable (MVP), que a menudo acaba siendo un poco un fantasma en sí mismo. (Los MVP casi nunca son tan pequeños como se planea o espera.) Sin embargo, el acto de intentar lanzar un MVP están en sí mismo un antídoto a los problemas mencionados anteriormente, así que incluso si ocurre cierto deslizamiento, están merece la pena el esfuerzo. Los procesos de desarrollo iterativo también abordan esto enfatizando la entrega regular y predecible de valor incremental, reforzada por el feedback de los usuarios finales reales.
Cómo evitar los anti-patrones
Incluso con las mejores intenciones, los anti-patrones ocurren cuando las personas no tienen experiencia o acceso a las mejores prácticas. Pueden sentirse tentados a tomar atajos debido a la presión de entregar a tiempo y dentro del presupuesto. Los equipos pueden no colaborar bien internamente o con socios externos, y las rupturas de comunicación empeoran la situación. En una prisa por Comienza el trabajo, la planificación y el diseño iniciales pueden ser descuidados. Aquí son algunos consejos para evitar los ejemplos anti-patrones que discutimos:
- Desafíos de programación en pizarra blanca: En lugar de resolver un problema abstracto en una pizarra, Crea un escenario práctico y enfocado con una muestra de código y pide mejoras.
- Considera que el candidato y el entrevistador trabajen juntos en un reto realista.
- Ofrece una tarea para hacer en casa que permita evaluar cómo el candidato afronta los problemas.
- Riesgo moral: Vincula incentivos al rendimiento y a los resultados a largo plazo. Haz claros los roles y la responsabilidad, con un sentido de propiedad individual.
- Utiliza herramientas que Haz claros los riesgos y faciliten tanto la comunicación abierta como una cultura que fomente el intercambio de preocupaciones.
- Define límites, procesos y barreras de seguridad en torno a los riesgos aceptables.
- Supervisa y mide, recibiendo la opinión de todos los interesados.
- Puliendo la bala: Para evitar el refinamiento constante de detalles menores, Define "suficientemente bueno" con un producto mínimo viable al principio del proceso y con métricas específicas.
- Define prioridades, comparando el valor con el tiempo y esfuerzo requeridos.
- Involucrar a las partes interesadas para determinar si están la inversión en un mayor refinamiento.
- Prueba y mide, para que te dispongas de datos para tomar decisiones sobre futuros refinamientos.
Lecturas recomendadas
son Hay suficientes patrones y anti-patrones en la industria para llenar libros, y de hecho se han escrito muchos sobre ellos. Al final, normalmente no están necesario memorizar listas de ellos, aunque se debería animar a desarrolladores especializados en ciertos lenguajes o frameworks a investigar aquellos específicamente dirigidos a esas áreas. Si te son interesado en aprender más sobre patrones y anti-patrones, he encontrado estos recursos valiosos en mi propia lectura:
- Las páginas de "Patrones de diseño de software" y "Anti-patrones" de Wikipedia ofrecen buenos ejemplos de temas de alto nivel.
- Los "Patrones de diseño" y "AntiPatrones" de SourceMaking contienen detalles útiles sobre tareas generales de ingeniería de software.
- Suficiente cuerda para dispararse en el pie: Reglas para la programación en C y C++, Alan Holub, McGraw Hill, 1995. Aunque este libro está centrado en C y C++, la mayoría de las reglas que cubre siguen aplicándose a casi cualquier lenguaje moderno.
- Para quienes están empezando su camino en programación y buscan los mejores lenguajes de programación para conoce.
Además, casi todos los lenguajes o frameworks tienen decenas de recursos disponibles si te simplemente buscar "NodeJS Patterns" o similares en cualquier motor de búsqueda. Animaría a todos los desarrolladores a hacer esto en sus campos particulares: incluso cuando creemos conocer buenas y malas prácticas, a veces puede sorprender cuando nos encontramos siguiendo un anti-patrón – siempre con las mejores intenciones, por supuesto.
Estas publicaciones son mías y no representan necesariamente la posición, estrategias u opinión de BMC.