80 puntos por GN⁺ 2025-08-26 | 5 comentarios | Compartir por WhatsApp
  • Estoy tratando de mejorar mis habilidades de diseño de software y me recomendaron estudiar bases de código existentes y bien diseñadas
  • Me pregunto cuáles de las bases de código con acceso público son consideradas el estándar de oro del diseño de software

1. Bases de código recomendadas

  • Proyectos grandes/representativos
    • Git, Postgres, CPython
    • El "modelo de tenientes" del kernel de Linux
    • UNIX v6, BSDs
  • Frameworks/bibliotecas
  • Sistemas/servidores
  • Juegos/casos especiales
  • Materiales educativos/de aprendizaje
  • Otros
    • Monocypher (biblioteca de criptografía)
    • Implementación del lenguaje Tcl

2. Leer código vs aprender de documentación/diseño

  • Límites de solo leer código
    • Una base de código muestra la implementación, pero oculta la intención del diseño y los trade-offs
  • Importancia de los documentos de diseño
    • Los registros de decisiones como ADR (Architectural Decision Records), los RFC de Rust y los PEP de Python son mucho más útiles para aprender diseño
    • Escribir documentos de diseño por sí mismo también puede ser un entrenamiento
  • Libros y referencias recomendados

3. Enfoque de aprendizaje centrado en la práctica

  • Experiencia y prueba/error
    • El diseño se aprende enfrentando problemas repetidamente y aprendiendo a evitarlos
    • Solo leer código no basta; se aprende escribiendo, fallando y resolviendo esos fallos
  • Aprendizaje guiado por el interés
    • Uno aprende más a fondo cuando construye proyectos que realmente le interesan
  • Bajo costo del fracaso
    • En software, el costo de fallar es más bajo que en la ingeniería física, por lo que aprender intentando y fallando funciona bien

4. Debate sobre la naturaleza de la ingeniería de software

  • Postura de ingeniería inmadura
    • Que cinco ingenieros propongan cinco soluciones distintas es visto como evidencia de inmadurez como disciplina de ingeniería
  • Postura de afinidad experimental
    • El software tiene menos restricciones, por lo que existen muchas soluciones posibles y no hay una respuesta fija como en la ingeniería física
  • La frontera entre arte e ingeniería
    • El diseño también puede ser un acto artístico con elementos estéticos, pero es ingeniería en la medida en que satisface requisitos funcionales
    • El software se ubica entre la flexibilidad artística y el rigor de la ingeniería

5. Métodos alternativos de aprendizaje

  • Analizar código malo
    • No solo estudiar código bien diseñado, sino también arreglar bases de código deficientes produce un gran aprendizaje
  • Aprender de tu propia base de código
    • La base de código del equipo interno fue mencionada como una de las fuentes de aprendizaje más valiosas
    • Eso sí, si el código del equipo es deficiente, conviene complementarlo con ejemplos externos
  • Aprendizaje ajustado al dominio
    • Leer bases de código parecidas al tipo de problema que quieres resolver es lo más efectivo

Ideas clave

  • Las bases de código bien diseñadas ayudan, pero el aprendizaje debe ir acompañado de entender la intención del diseño y pasar por prueba y error
  • Más que la lectura de código en sí, los documentos de diseño y los registros de decisiones son el material de aprendizaje clave
  • Proyectos representativos y de alta calidad (Git, Postgres, CPython, la std de Rust, etc.) tienen un gran valor educativo
  • No solo se aprende de buen código, sino que aprender de código deficiente y del propio código resulta más práctico a largo plazo

Resumen de comentarios principales

Recomendaciones de bases de código destacadas (CraigJPerry)

  • Servidor de correo Postfix
    • Su arquitectura centrada en la seguridad mostraba una estructura similar a los microservicios incluso antes de que existiera ese concepto
    • Mientras los microservicios modernos se enfocan en la distribución a gran escala entre organizaciones, Postfix fue diseñado para seguridad y simplicidad
  • Spring Framework
    • Refleja una cultura que consideró profundamente las necesidades de los desarrolladores Java en entornos empresariales
    • Permite aprender un enfoque de diseño centrado en el usuario
  • Git
    • Si se entienden la base de datos de objetos (blob, tree, commit) y el concepto de referencias, el resto es una expansión gradual
    • Se presenta como un buen ejemplo de diseño basado en la extensión coherente de conceptos centrales
  • Varnish
    • Un proxy reverso de alto rendimiento con una base de código tan bien organizada que también sirve como herramienta de aprendizaje
  • Modelo de tenientes del kernel de Linux
    • No es una base de código, pero vale la pena como modelo de gestión de software a gran escala
  • Más que simplemente "código bien diseñado", son ejemplos en los que las decisiones de diseño dejan una fuerte impresión

Énfasis en aprender de bases de código reales de trabajo (crystal_revenge)

  • El mayor valor de aprendizaje puede obtenerse de la base de código de tu propio equipo
  • En el proceso confuso que conecta requisitos reales con la implementación, se experimentan al mismo tiempo buenas y malas decisiones
  • La restricción más importante en la práctica es la presión de tiempo, y lo clave es aprender a equilibrar entre el diseño ideal y la realidad
  • El buen software es aquel que resuelve las necesidades del usuario, y con la experiencia repetida uno aprende diseños que aumentan las probabilidades de éxito

Enlaces a debates y materiales previos (sprobertson)

Código vs documentos de diseño (alphazard)

  • Una base de código es solo el resultado de la implementación, no el diseño en sí
  • Para aprender diseño, es más efectivo escribir documentos de diseño
    • Los documentos deben ser lo bastante claros como para que otra persona pueda implementar exactamente lo mismo
    • Enumerar alternativas y registrar por qué fueron descartadas deja evidencia de las consideraciones de diseño
  • Un buen diseñador es alguien que considera un espacio de diseño más amplio y elige el punto adecuado dentro de él

Énfasis en entender el sistema completo (RossBencina)

  • El proceso de entender una base de código completa tiene mucho valor
    • No solo entrena para reconocer código bien diseñado, sino también para ver el panorama general del sistema
    • Visualizar relaciones con diagramas como UML puede ayudar
  • Enfoque de aprendizaje:
    • Es útil leer código de software parecido a lo que uno está desarrollando
    • Como punto de partida, se recomiendan bases de código de dominios que ya conoces bien (frameworks web, servidores web, biblioteca estándar de Python, VSCode, etc.)
    • Al principio, conviene empezar por programas pequeños y dominios familiares

Criterios de un buen diseño (mamcx)

  • Un buen diseño son los objetivos y las ideas; la base de código muestra hasta qué punto fueron implementados
  • Un buen diseño no debe limitarse a adjetivos como "rápido" o "seguro", sino incluir consideraciones concretas y registro de trade-offs
  • Casos observables de esto: Erlang, Pascal temprano y muchos diseños de RDBMS
  • La biblioteca estándar de Rust enfatiza seguridad y consistencia, y su código y documentación lo reflejan fielmente, por lo que es un buen material de aprendizaje

Decisiones de diseño invisibles (ben30)

  • Al mirar una base de código bien diseñada, la parte más importante es lo que no se ve
    • Decisiones de ausencia, como excluir complejidad, evitar abstracciones innecesarias o rechazar ciertos patrones, son clave
  • Para complementar eso, se pueden usar ADR (Architectural Decision Records)
    • Registran alternativas, motivos para descartarlas y fundamentos de la elección, preservando el contexto
    • Son de gran ayuda tanto para futuros mantenedores como para herramientas de IA
  • Al aprender, es efectivo revisar proyectos que, además del código, también incluyan documentos de decisiones de diseño como ADR, RFC o PEP

5 comentarios

 
shaffr0n 2025-08-27

Vi una entrevista en la que Evan You (creador de Vue.js y Vite) decía que TJ Holowaychuk, creador de express.js, había diseñado algo limpio y hermoso, así que me puse a leer el código varias veces. Aunque no logré entender la visión completa, en general me dio mucho la impresión de que el código no es complejo y está escrito de forma limpia, solo con la lógica realmente necesaria.

Además, los comentarios están bien puestos, así que aunque es código de hace 10 años, fue fácil entender la inferencia de tipos y el formato de los DTO.

 
wedding 2025-08-27

Tomar como referencia una publicación de blog de 2009 cubierta de comentarios spam...

 
GN⁺ 2025-08-26
Opinión de Hacker News
  • No sé si solo me pasa a mí, pero siento que la forma más efectiva es chocar con problemas reales varias veces e ir aprendiendo por tu cuenta cómo evitarlos. Con el tiempo, naturalmente empiezas a simular en tu cabeza qué problemas podrían surgir más adelante, y al final el diseño también termina siendo un juicio cuidadoso sobre prever y evitar distintos problemas futuros, evaluar con cuánto esfuerzo conviene evitar cada uno, y si un solo diseño puede resolver varios problemas a la vez, entre otros trade-offs.

    • A mí me pasa igual. Enfoques como "resolver ejercicios" o "estudiar codebases" no me funcionaban. Aprendo de forma natural cuando construyo algo que de verdad me interesa, buscando precisión y cuidado en los ejemplos. Pero a veces siento que todavía me falta nivel. Creo que si pudiera leer código con fluidez, como si leyera un libro, y visualizar en mi cabeza cómo funciona, estudiar también sería más divertido.

    • Lo que me hace pensar escuchar eso de aprender chocando una y otra vez con problemas es que la ingeniería de software todavía no es una disciplina madura. Imagínate si construyéramos puentes o casas de esa manera, o si los cirujanos se entrenaran así; solo pensarlo ya da miedo. Con el tiempo surgirán estándares y normas, pero por ahora todo sigue siendo muy cambiante. Si juntas a cinco ingenieros de software y les planteas un problema, no solo vas a obtener cinco soluciones totalmente distintas, sino que además habrá fuertes desacuerdos sobre cuál es la correcta. No creo que una actitud de "reconozco una buena solución cuando la veo" sea suficiente para hablar de ingeniería de verdad.

    • Yo también he aprendido de manera constante así hasta ahora y seguramente seguiré haciéndolo. Aprender de código real de producción sería un reto nuevo para mí. No sé qué tanto valor tenga, pero de todos modos suena divertido.

    • Creo que se parece a aprender a manejar subiéndose al auto por primera vez, chocando, y luego reflexionando para no volver a chocar la próxima vez. En realidad, se necesitan ambas cosas. En la conducción normal en carretera casi nunca llevamos las cosas al límite, así que no se aplica tan directamente, pero en algo como las carreras sí es indispensable saber exactamente dónde está el límite de lo que puedes exigir. Claro, no creo que debamos tratar nuestro trabajo como si fuera una competencia. Pero si no lees ni estudias, literalmente te va a tomar muchísimo tiempo y además no van a faltar los choques y las fallas. Por eso yo diría: lean, y lean mucho. Puede que ahora no sientas la necesidad, pero más adelante, cuando acumules experiencia, ese conocimiento seguro te va a servir en algún momento, y no te va a agarrar desprevenido como la primera vez que aprendes que en una bajada hay que frenar con motor y bajar a una marcha más corta.

    • Ese es exactamente el punto.

  • Lo primero que se me viene a la cabeza con esta pregunta es "el codebase de tu equipo". No hay mejor forma de aprender diseño de software de manera efectiva que entender a fondo por qué se adoptaron buenas y malas soluciones para problemas reales. El software es, en esencia, esa capa intermedia compleja entre los requisitos de los usuarios y el comportamiento de las máquinas. Si ese caos no existiera, ya estaría automatizado y ni siquiera necesitaríamos software. En software, perseguir solo un ideal abstracto muchas veces lleva a malas decisiones. En la práctica, uno reduce el ensayo y error cuando entiende "por qué ciertas presiones llevaron a tomar determinada decisión". Al mismo tiempo, hay que aprender metodologías prácticas para trabajar rápido y con efectividad. El mayor reto en el mundo real es el tiempo. Casi no se habla de eso en el diseño teórico de software, pero en la práctica siempre trabajas bajo presión para entregar código rápido. Muchas veces no hay tiempo para hacerlo como te gustaría o de la mejor manera posible. Un buen software es software que resuelve necesidades reales de los usuarios. Existen soluciones de diseño que producen ejecuciones exitosas con más frecuencia, y la mejor manera de encontrarlas es examinar a fondo el código real que uno mismo escribe.

    • ¿Y qué habría que hacer si quien pregunta está buscando consejo externo porque siente que el software de su equipo es un desastre? ¿O si simplemente es un estudiante universitario?

    • Nunca había pensado que el tiempo necesario para implementar algo también pudiera ser un criterio para evaluar la calidad del diseño, pero me parece totalmente válido. Yo también estoy aprendiendo muchísimo del codebase de mi equipo. Gran parte de eso viene tanto de las cosas buenas en los diseños sobresalientes como de tener que googlear por mi cuenta cuando me topo con partes no tan buenas.

  • Es material de hace varios años, pero existe la serie "The Architecture of Open Source Applications", en la que colaboraron líderes de muchos proyectos open source, y se puede leer gratis en línea
    https://aosabook.org/en/index.html

  • Esta pregunta ya ha salido varias veces, así que reuní algunos enlaces de referencia

  • Código fuente de Yanderedev

  • No creo tener suficientes credenciales para dar la respuesta correcta, pero hace unos 15 años leí con mucho gusto un libro llamado "Code Reading". Encaja perfecto con este tema
    https://www.spinellis.gr/codereading/
    Tabla de contenido: https://www.spinellis.gr/codereading/toc.html
    Creo que también había otro libro con un nombre parecido, pero no lo recuerdo bien.

  • En la práctica, un codebase muchas veces contiene más implementación que diseño. Por ejemplo, incluso si reescribes todo en otro lenguaje, el diseño puede mantenerse. Recomiendo practicar escribiendo documentos de diseño. No te preocupes por cómo deban verse ni te amarres a una plantilla. Lo más importante es que otra persona pueda tomar ese documento e implementarlo tal cual. Además, el documento en sí puede servir como un "registro del razonamiento". Basta con dejar claro qué enfoque elegiste y por qué no elegiste otras alternativas que también existían. Reconocer y comparar alternativas desde antes puede transmitirle al lector la confianza de que sí hubo una reflexión suficiente. Lo que hace un diseñador de sistemas "bueno" es observar un espacio de diseño más amplio que los demás y encontrar buenos puntos de manera consistente. Elige un problema, explora distintos espacios de diseño y documenta por qué uno es mejor que otro.

  • Todo debería empezar con la pregunta: "¿qué problema quiero resolver?". Busca codebases que hayan resuelto ese problema y analiza con atención cómo lo implementaron en la práctica. Hay que tener presente que un buen diseño está muy ligado al contexto específico del dominio. Creo que el Internal Model Principle de Wonham también aplica al código. Por ejemplo, yo quería resolver el problema de las pruebas unitarias para targets embebidos, así que analicé proyectos open source relacionados y examiné críticamente por qué cada parte del código estaba escrita de cierta forma. Mientras construyo mi propia solución y vuelvo a apoyarme en esos codebases, sigo aprendiendo más a medida que entiendo mejor mi dominio.

  • Según mi experiencia (30 años en software, 25 en arquitectura práctica, maestría en arquitectura de sistemas en MIT), en abstracto no existe eso de un diseño "bueno". Sí existen diseños malos, es decir, que producen malos resultados, pero el criterio de qué es "bueno" depende del contexto. Influye qué estás construyendo, requisitos como seguridad o protección, y sobre todo el equipo que va a implementarlo y la estructura de ese equipo. En un equipo formado solo por juniors, un diseño sofisticado puede malinterpretarse y terminar arruinado. Como dice la ley de Conway, la estructura del equipo de desarrollo termina reflejada en el software.

    • Algo que definitivamente he aprendido al estudiar diseño de software es que no existe una solución universal. Ojalá existiera, pero a veces resulta frustrante elegir la mejor opción entre distintas arquitecturas y paradigmas. Aun así, si reflejas bien los requisitos, el abanico de opciones sí se reduce bastante. Ahora mismo trabajo con sistemas embebidos donde la seguridad es especialmente importante, y ese entorno hace que a veces tome decisiones que en otros contextos ni siquiera tendría sentido considerar.

    • Al final, la clave es evitar compromisos realmente absurdos y también esquivar las peores decisiones cuando miras las cosas con perspectiva amplia. Lo que siempre siento en el trabajo real es que esto no es tanto una búsqueda de la mejor arquitectura, sino una lucha constante por "evitar decisiones fundamentalmente malas".

  • Hace tiempo hice una lista de recomendaciones muy simple, y todavía sigue vigente
    https://medium.com/@012parth/what-source-code-is-worth-studying-8755f88f8de5

 
roxie 2025-08-27

Hay una trampa a la mitad..

 
ffdd270 2025-08-27

¿El código fuente de Yanderedev... jajaja?