Aquí hay una
cita de Linus Torvalds para 2006 :
Soy un gran creyente en el desarrollo de código en torno a los datos, y no al revés, y creo que esta es una de las razones por las que git tuvo bastante éxito ... De hecho, sostengo que la diferencia entre un mal programador y un buen programador es si piensa más importante su código o sus estructuras de datos. Los malos programadores se preocupan por el código. Los buenos programadores se preocupan por las estructuras de datos y sus relaciones.
Lo cual es muy similar a
la "regla de presentación" de Eric Raymond de 2003 :
Convierta el conocimiento en datos para que la lógica del programa se vuelva estúpida y confiable.
Aquí hay un resumen de ideas como
las que pensó Rob Pike en 1989 :
Los datos dominan. Si elige las estructuras de datos correctas y organiza todo bien, entonces los algoritmos casi siempre serán evidentes. Las estructuras de datos, no los algoritmos, juegan un papel central en la programación.
Cita a
Fred Brooks de 1975 :
La presentación es la esencia de la programación.
Detrás del dominio está el ingenio que hace
Programas económicos y rápidos. Este es casi siempre el resultado.
avance estratégico, no habilidad táctica. A veces tan estratégico
un avance es un algoritmo, como una transformación rápida de Fourier,
propuesto por Cooley y Tukey, o reemplazando n ² comparaciones con n log n al ordenar.
Más a menudo, un avance estratégico viene como resultado de la presentación
datos o tablas. El núcleo del programa está aquí. Muéstrame los diagramas de flujo sin mostrar las tablas, y seguiré por mal camino. Muéstrame tu
Es muy probable que no se necesiten tablas y diagramas de flujo: serán obvios.
Entonces, durante casi medio siglo, las personas inteligentes han dicho una y otra vez: enfóquense primero en los datos. Pero a veces parece que este es el consejo más inteligente que todos olvidan.
Daré algunos ejemplos reales.
Sistema altamente escalable que falló
Este sistema fue creado originalmente con la expectativa de una escalabilidad increíble con una gran carga en la CPU. Nada sincrónico. En todas partes devoluciones de llamada, colas y grupos de trabajo.
Pero hubo dos problemas. La primera fue que la "carga del procesador" no fue tan intensa: una tarea tomó un máximo de unos pocos milisegundos. Así que la mayoría de la arquitectura hizo más daño que bien. El segundo problema era que el "sistema distribuido altamente escalable" en realidad solo funcionaba en una máquina. Por qué Debido a que toda la comunicación entre los componentes asíncronos se realizó utilizando archivos en el sistema de archivos local, que ahora se ha convertido en un cuello de botella para cualquier escala. El diseño original no estaba vinculado a los datos en absoluto, con la excepción de proteger los archivos locales en nombre de la "simplicidad". La parte principal del proyecto se dedicó a toda esta arquitectura adicional, que era "obviamente" necesaria para hacer frente a la "carga pesada" en la CPU.
Arquitectura orientada a servicios que sigue orientada a datos
Este sistema siguió el diseño de microservicios de aplicaciones de un solo propósito con API REST. Uno de los componentes era una base de datos en la que se almacenan los documentos (principalmente respuestas a formularios estándar y otros documentos electrónicos). Naturalmente, ella configuró la API para guardar y recuperar datos, pero rápidamente necesitó una funcionalidad de búsqueda más compleja. Los desarrolladores consideraron que agregar esta función a un documento API existente contradice los principios del diseño de microservicios. Dado que 'buscar' es esencialmente diferente de 'get / put', la arquitectura no debería combinarlos. Además, planearon usar una herramienta de terceros para trabajar con el índice, por lo que la creación de un nuevo servicio de 'búsqueda' también tenía sentido por este motivo.
Como resultado, se crearon una API de búsqueda y un índice de búsqueda, que esencialmente se convirtió en un duplicado de los datos en la base de datos principal. Estos datos se actualizaron dinámicamente, por lo que cualquier componente que cambie los datos del documento a través de la API de la base de datos principal también debe enviar una solicitud para actualizar el índice a través de la API de búsqueda. Con la API REST, esto no se puede hacer sin una condición de carrera, por lo que los dos conjuntos de datos se desincronizarían de vez en cuando.
A pesar de lo que prometía la arquitectura, las dos API estaban estrechamente relacionadas a través de sus dependencias de datos. Más tarde, los desarrolladores reconocieron que el índice de búsqueda debería combinarse con un servicio de documentos común, y esto hizo que el sistema fuera mucho más fácil de mantener. Doing One funciona a nivel de datos, pero no a nivel de verbo.
Trozo de barro fantásticamente modular y configurable
Este sistema era una especie de canalización de implementación automatizada. El equipo de desarrollo original quería hacer una herramienta lo suficientemente flexible como para resolver problemas de implementación en toda la empresa. Escribieron un conjunto de componentes de complemento con un sistema de archivos de configuración que no solo configuró los componentes, sino que también actuó como un
lenguaje específico de dominio (DSL) para programar cómo encajan los componentes en la tubería.
Avancemos rápidamente a unos pocos años, y la herramienta se convirtió en "el mismo programa". Había una larga lista de errores conocidos que nadie había solucionado. Nadie quería tocar el código por miedo a romper algo. Nadie ha usado la flexibilidad de DSL. Todos los usuarios copiaron y pegaron la misma configuración de trabajo garantizada que todos los demás.
¿Qué salió mal? Aunque el documento original del proyecto solía utilizar palabras como "modular", "desconectado", "ampliable" y "personalizado", no dijo nada sobre los datos. Por lo tanto, las dependencias de datos entre componentes se procesaron de forma no regulada utilizando un blob JSON común a nivel mundial. Con el tiempo, los componentes hicieron suposiciones cada vez más indocumentadas sobre lo que se incluye o no en el blob JSON. Por supuesto, DSL permitió que los componentes se reorganizaran en cualquier orden, pero la mayoría de las configuraciones no funcionaron.
Las lecciones
Elegí estos tres proyectos, porque es fácil explicar la tesis general usando su ejemplo, sin tocar los otros. Una vez intenté crear un sitio web y, en cambio, me quedé colgado de algún tipo de base de datos XML servil que ni siquiera resolvió mis problemas de datos. Hubo otro proyecto que se convirtió en una apariencia rota de la mitad de la funcionalidad de
make
, nuevamente porque no pensaba lo que realmente necesitaba. Ya escribí sobre el tiempo dedicado a crear una
jerarquía interminable de clases OOP que deberían haberse codificado en los datos .
Actualización:
Aparentemente, muchos todavía piensan que estoy tratando de burlarme de alguien. Mis colegas reales saben que estoy mucho más interesado en solucionar problemas reales y no culpar a quienes generaron estos problemas, pero, bueno, esto es lo que pienso sobre los desarrolladores involucrados en estos proyectos.
Honestamente, la primera situación se produjo claramente porque el arquitecto del sistema estaba más interesado en aplicar el trabajo científico que en resolver un problema real. Muchos de nosotros podemos ser culpados por esto (yo también), pero realmente molesta a nuestros colegas. Después de todo, tendrán que ayudarnos cuando nos cansemos de un juguete. Si se reconoce a sí mismo, no se ofenda, simplemente deténgase (aunque preferiría trabajar con un sistema distribuido en un nodo que con cualquier sistema en mi "base de datos XML").
En el segundo ejemplo, no hay nada personal. A veces parece que todo el mundo dice lo maravilloso que es compartir servicios, pero nadie habla de cuándo es mejor no hacerlo. La gente todo el tiempo aprende de su propia experiencia amarga.
La tercera historia realmente le sucedió a algunas de las personas más inteligentes con las que he trabajado.
(Fin de la actualización).
La pregunta "¿Qué se dice sobre los problemas creados por los datos?" Resulta ser una prueba de fuego bastante útil para un buen diseño del sistema. También es muy conveniente para identificar falsos "expertos" con sus consejos. Los problemas con la arquitectura de sistemas complejos y complicados son problemas de datos, por lo que a los falsos expertos les gusta ignorarlos. Le mostrarán una arquitectura sorprendentemente hermosa, pero no dirán nada sobre para qué datos son adecuados y (lo más importante) para qué datos no son adecuados.
Por ejemplo, un falso experto podría decir que debería usar el sistema pub / sub porque los sistemas pub / sub están acoplados libremente y los componentes acoplados libremente son más fáciles de mantener. Suena hermoso y da hermosos diagramas, pero es lo contrario del pensamiento. Pub / sub no
hace que sus componentes estén débilmente acoplados; pub / sub en
sí mismo está débilmente acoplado, lo que puede o no satisfacer sus necesidades de datos.
Por otro lado, una arquitectura orientada a datos bien diseñada es de gran importancia. Programación funcional, malla de servicio, RPC, patrones de diseño, bucles de eventos, lo que sea, cada uno tiene sus propios méritos. Pero personalmente, vi que los sistemas de producción mucho más exitosos funcionan en
viejos DBMS aburridos .