El más frecuente que he visto, uno que parece casi universal, se puede resumir de manera muy simple: pensar que tiene un problema que resolver cuando realmente tiene dos (o más), y luego tratar de resolverlos como un problema único.
Esto es realmente una falla al analizar el problema completamente. “Dividir y conquistar” se trata de la mejor herramienta analítica que tenemos para robustecer las cosas, y la mayoría de los problemas se pueden dividir en al menos dos problemas más simples. Si los resuelve, puede combinar las soluciones para resolver el problema más grande.
Todo se reduce a la combinatoria: si el problema A puede dar como resultado 3 estados posibles, y el problema B puede dar como resultado 10 estados posibles, entonces puede escribir código que trate con cada uno de ellos y saber con certeza que los ha capturado a todos o escriba una solución combinada que trate con 3 * 10 posibles estados combinados. Este último va a ser más complejo, porque tiene que manejar 30 casos en lugar de 13. Y cuanto más complejo es el código, más probabilidades hay de tener problemas simplemente porque hay más código para tener errores.
Entonces, si ve algún código que parece ser casos de muerte por esquina, o una pila gigante de declaraciones de casos y si, y prueba más de una cosa, entonces probablemente esté en presencia de un caso incompleto problema analizado.
Estas cosas generalmente parecen funcionar (o incluso son inteligentes) cuando son nuevas; es más tarde, cuando descubres que necesitas manejar las combinaciones de estados que se tragaron con un código que no consideraba interesantes los resultados de ambos problemas, las cosas se pusieron feas.
Un ejemplo común es confundir y engordar la autenticación y la autorización . Autenticación es donde el sistema descubre quién eres ; autorización es donde se da cuenta de lo que puede hacer . Puede ver las consecuencias de no resolver ese problema en el corazón de Unix: el usuario root
o superusuario siempre tiene un id (el problema de autenticación ) de cero, y el usuario raíz tiene un * role * (el problema de autorización ) que hacer cualquier cosa, incluida la eliminación del sistema operativo. Eso suena genial hasta que el sistema operativo ejecute contenedores (por ejemplo, Docker), y cada contenedor debe tener su propio superusuario root
, pero solo hay un cero , y eso es lo que el universo del código Unix va a probar para ver si usted ‘ re root
– no hay rasgadura que de 45 años de software ahora. Un amigo mío me dio una demostración de Kubernetes, una herramienta de implementación de implementación de Docker, el otro día, que tiene una rabieta si un contenedor necesita ejecutar un proceso como raíz. Él vio eso como algo normal, por supuesto que no puedes hacer eso. No es normal (y de hecho, otro SO que tiene contenedores, SmartOS, no tiene esa limitación). Entonces la idea de que hay un superusuario, autorizado para hacer cualquier cosa, que siempre se identifica con el cero de la identificación , funciona de maravilla hasta que necesite dos superusuarios. Y en ese momento puede haber miles de millones de líneas de código que debe ejecutar, que todas suponen que root
= 0 y que solo hay un superusuario. En ese punto estás jodido.
Verdaderamente, nadie es inmune a fallar en romper los problemas lo suficiente. Considere HTTPS, el protocolo seguro que usan los navegadores web. Combina dos problemas heterogéneos y los trata como uno solo:
- Sabiendo que la comunicación está encriptada
- Identificando con quién te estás comunicando
Ahora, debe resolver estos dos problemas para tener una navegación segura. Y la criptografía proporciona excelentes herramientas para resolver ambas. Pero el hecho de que HTTPS fue diseñado con la fantasía de que esos son un problema único crea todo tipo de consecuencias desagradables para quienes lo usan:
- Una industria de certificados parasitarios que cobra masivamente por los certificados
- No hay forma de tener un mecanismo alternativo para identificar con quién se está comunicando: está atrapado con lo que HTTPS le brinda si es adecuado para usted o no (o si lo necesita)
Aprende, cada vez que resuelves un problema en el código, pregúntate, sin piedad y repetidamente, ¿Puedo dividir este problema en dos problemas más simples? antes de escribir una línea de código. Hazlo de forma recursiva hasta que llegues a problemas que no se pueden reducir más o que ya tienes una solución. Por lo general, una vez que los problemas se vuelven lo suficientemente pequeños, se llega a los ya resueltos, donde puede usar su código existente o en las bibliotecas. Terminas escribiendo menos código, y los resultados son más robustos y más legibles para los demás, no terminarás haciendo reescrituras masivas cuando descubras una nueva necesidad, y obtendrás soluciones que puedes reutilizar.
Y si alguien te dice que hacer ese tipo de análisis inicial no es “ágil” o que es “cascada” … dales una botella, asegúrate de eructarlos, ponles un binky en la boca y ponlos a dormir una siesta. Luego haz el análisis.