Guía de referencia rápida para The Pragmatic Programmer, en español

The_pragmatic_programmer 

El libro "The Pragmatic Programmer" es para nosotros (y para muchos) todo un libro de culto. No sólo sirve para aconsejar al programador, lo puedes usar para casi cualquier otro proyecto. Un libro indispensable para el informático, ya que tarde o temprano, te tocará programar y este libro te dará consejos que realmente no olvidarás.

En la web Coding Horror hemos visto esta Pragmatic Quick Refence y para honrar este magnífico libro, nos hemos tomado la libertad de traducirlo entre tuxotron y yo para tener esta misma guía pero en español, esperamos que os guste:

Guía Pragmatic Programmer en castellano:

Cuida tu obra de arte. ¿Por qué desperdiciar tu vida desarrollando software sino te preocupas en hacerlo bien?

¡Piensa!, sobre tu trabajo. Desconecta el piloto automático y toma el control. Critica y evalúa constantemente tu trabajo.

Proporciona opciones, no excusas. En vez de excusas, propón opciones. No digas que no se puede hacer algo, explica mejor lo que sí puedes hacer.

No vivas con ventanas rotas. Corrige malos diseños, decisiones equivocadas y el código mal escrito cuando lo veas.

Sé un catalizador para cambios. No puedes forzar que la gente cambie. En vez de eso, muestra cómo podría ser el futuro y ayúdalos a participar en tu creación.

Recuerda el “Gran Cuadro”. No te obsesiones con los detalles porque hacen olvidarte de lo que ocurre alrededor.

Hacer de la calidad un requisito imprescindible. Involucra a los usuarios para determinar las necesidades de calidad reales del proyecto.

Invertir regularmente en conocimiento. Haz de aprender un hábito

Analiza de forma crítica lo que lees y escuchas. No te dejes convencer por vendedores, dogma o medios. Analiza la información en tus términos y en basada en tu proyecto.

Importa tanto lo que dices como la forma de decirlo. No tiene sentido tener buenas ideas sino las transmitimos con eficacia.

No te repitas. Cada pieza de conocimiento debe de tener una única e inequívoca representación dentro de un sistema.

Hazlo fácil de reutilizar. Si es fácil de reutilizar, la gente lo hará reutilizable. Crea un entorno que apoye la reutilización.

Elimina los efectos entre cosas no relacionadas. Los componentes de un diseño son autónomos, independientes y tienen un único propósito bien definido.

 No hay decisiones finales. Las decisiones no se deben grabar en una piedra, sino en la arena de la playa. Cualquier decisión debe ser susceptible a cambio.

Tracea para llegar a to objetivo. Haz distintas pruebas y tracea los resultados para ver cómo se van compenetrando para llegar a nuestro objetivo.

Usa prototipos para aprender. Crear prototipos es un experiencia para el aprendizaje. Su valor no reside en el código generado, sino en las lecciones que aprendes al crearlo.

Programa cerca del dominio.. Diseña y programa usando el mismo lenguaje usado por el usuario.

Haz estimaciones para evitar sorpresas. Haz una estimación antes de empezar. Podrás adelantarte a los posibles problemas futuros.

Sincroniza tu agenda con el código. Usa la experiencia que vayas ganando para refinar las escalas temporales de entrega del proyecto.

Guarda tu conocimiento en texto plano. El texto plano nunca será obsoleto. Ayuda a aprovechar tu trabajo y simplifica la depuración así como las pruebas. 

Usa el poder de la línea (Shell) de comandos. Usa la línea de comandos (Shell) para resultados seguros que no sean interferidos por las interfaces gráficas.

Utiliza un único buen editor. El editor debe de ser una extensión de tu mano. Asegúrate que es configurable, ampliable (plugins) y programable.

 Siempre controla el código fuente. El control del código fuente es una máquina del tiempo, siempre puedes volver atrás.

Arregla el problema, no la culpa. No importa de quién o de qué es la culpa, sigue siendo un problema de todas formas y todavía necesita ser reparado.

No te asustes de depurar (debugging). Respira profundamente y PIENSA en la causa del error.

El error no es de la “select”. Es raro encontrar un error en el Sistema Operativo o en el compilador, o incluso en librerías de terceros. El error (bug) siempre es más probable que esté en la aplicación.

 No asumes nada, pruébalo. Prueba tu hipótesis en el entorno actual que tengas, con datos reales y condiciones límites.

 Aprende un lenguaje para manipular texto. Gastas una gran parte del día peleando con texto. ¿Por qué no hacer que el ordenador haga el trabajo por ti?

Escribe código que escriba código. Los generadores de código aumentan la productividad y evitan la duplicación.

No se puede escribir el software perfecto. El software no puede ser perfecto. Protege el código y a los usuarios de errores inevitables.

Diseña con contratos. Recurre a los contratos para documentar y comprobar que el código hace realmente lo que tiene que hacer.

Error tempranero. Un error cuanto antes sea detectado mejor, hará menos daño que aquel que se detecte tarde, hará que creemos que la aplicación funciona.

Usa afirmaciones para prevenir lo imposible. Las afirmaciones validan tu hipótesis. Úsalas para proteger el código de un mundo desconocido.

 Usa excepciones para los problemas excepcionales. El abuso del uso de excepciones pueden convertir tu aplicación en poco legible y sotenible. Usa las excepciones para casos excepcionales.

Acaba lo que empiezas. Siempre que sea posible, la rutina o el objeto asignado a un recurso debe de ser borrado cuando ya no sea necesario.

 Minimiza el acoplamiento entre módulos. Evita el acoplamiento debido al código “tímido” y aplica la Ley de Demeter.

Configura, no integres. Implementa las opciones para una tecnología usando opciones de configuración, no a través de integración ó ingeniería.

Coloca abstracciones en código, detalles en metadatos. Programa para el caso general, y coloca las especificaciones fuera del código base compilado.

Analiza el flujo de trabajo para mejorar la concurrencia. Aprovecha la concurrencia en el flujo de trabajo del usuario.

Diseña servicios de uso. Diseña en términos de servicios independientes, detrás de objetos concurrentes bien definidos, interfaces consitentes.

Siempre diseña para la concurrencia. Permite la concurrencia, y diseñarás interfaces más limpias.

 Separa las vistas desde los modelos. Gana flexibilidad a bajo coste diseñando tu aplicación en términos de modelos y vistas.

Usa pizarras para coordinar el flujo de trabajo. Usa las pizarras para coordinar agentes y hechos dispares, manteniendo la independencia y el aislamiento entre los participantes.

No programes por coincidencia. Confíe sólo en las cosas confiables. Ten cuidado con la complejidad accidental, y no confundas una feliz coincidencia con un plan organizado.

Haz una estimación del orden de tus algoritmos. Ten una idea de la longitud de las cosas antes de empezar a escribir código.

Prueba tus estimaciones. El análisis matemático no te lo dice todo. Prueba el tiempo consumido por tu código en su entorno final.

Refactoriza pronto, refactoriza a menudo. Así como quitas las malas hierbas de un jardín y lo reorganizas, reescribe, haz de nuevo y rediseña el código cuando sea necesario. Arregla la raíz del problema.

Diseño a prueba. Empieza a pensar en las pruebas antes de escribir una línea de código.

Prueba tu software, o lo harán tus usuarios. Prueba sin piedad. No hagas que los usuarios encuentren los errores por ti.

No uses asistentes de código que no comprendas. Los asistentes pueden generar montones de código. Asegúrate de entender todo antes de incorporarlo a tu proyecto.

No reunas requisistos, búscalos. Los requisitos rara vez están en la superficie. Están enterrados bajo capas de supuestos, conceptos erróneos y política.

Trabaja como un usuario para pensar como un usuario. Esta es la mejor forma de conocer cómo funciona el sistema que utilizarán realmente.

Las abstracciones viven más que los detalles. Invertir en abstracción, no en la implementación. Las abstracciones pueden sobrevivir.

Usa un glosario del proyecto. Crea y mantén una única fuente de todos los términos y vocabulario específico de un proyecto.

No pienses fuera de la caja, encuentra la caja. Cuando nos enfrentamos a un problema imposible, identifica las limitaciones reales. Tienes que preguntarte “¿Se tiene que hacer de esta manera? ¿Hay que hacerlo en todos?

Empieza cuando estés listo. Has ido adquiriendo experiencia toda tu vida. No ignores las dudas que te puedan surgir.

Algunas cosas son mejores cuando las acabas que cuando se describen. No caigas en la espiral de las especificaciones, en algún momento tenemos que empezar a programar.

No seas un esclavo de los métodos formales. No adoptes ciegamente cualquier técnica sin suponerla en el contexto de tus prácticas de desarrollo y capacidades.

Las herramientas costosas no producen mejores diseños. Ten cuidado con las exageraciones de los proveedores, el dogma de la industria, y el precio. Juzga las herramientas en función a sus méritos.

Organiza los equipos alrededor de la funcionalidad. No separes diseñadores de programadores ni los probadores  (testers) de los modeladores de datos.  Construye equipos en función de tu manera de construir código.

No uses el procedimientos de manual. Un Shell script o fichero por lotes se ejecutará las mismas instrucciones, en el mismo orden, una y otra vez.

Prueba pronto. Prueba a menudo. Prueba de forma automática. Las pruebas que se ejecutan cada vez que compilas son más efectivas que los planes de pruebas teóricos.

La programación no está terminada hasta que todos los tests hayan pasado. Queda todo dicho.

Usa saboteadores para probar tu prueba. Introducir “bugs” a propósito en una copia separada de la fuente para verificar que las pruebas detectan dicho error.

Prueba la cobertura de un estado, no la cobertura del código. Identifica y pon a prueba los estados de los programas. Probar sólo líneas de código no es suficiente.

Encuentra errores una sola vez. Una vez que los probadores (humanos) encuentran un error, esta debe de ser la última vez que se encuentra. A partir de ahora tienen que ser las pruebas automáticas las que comprueben los errores.

El inglés es un lenguaje de programación. escribir documentos igual que escribes código: respeta el principio DRY (No Te Repitas, Dont Repeat Yourself), usa metadatos, MVC, generación automática, así sucesivamente.

Crea la documentación con el código. No la metas con calzador. La documentación creada separadamente del código acaba siendo poco precisa y actualizada.

De forma gradual, aumenta las expectativas de los usuarios. Cuando comprendas las expectativas de los usuarios, entonces es el momento de ofrecer un poco más.

 Firma tu trabajo. Los artesanos de la Edad Media se sentían orgullosos de firmar su trabajo. Tu también deberías.

Lenguajes a aprender

¿Cansado de C, C++ y Java? Prueba CLOS, Dylan, Eiffel, Objetive-C, Prolog, Smalltalk ó TOM.

El acróstico de la SABIDURÍA

¿Qué quieres que aprendan? ¿Cuál es su interés en lo que tienes que decir? ¿Cómo son de sofisticados? ¿Cuánto detalle quieren? ¿Quién quieras que tenga la información? ¿Cómo puedes motivarlos para que te escuchen?

 Cómo mantener la ortogonalidad

  • Diseñar los componentes independientes y bien definidos.
  • Mantén el código desacoplado.
  • Evita los datos globales.
  • Refactoriza las funciones similares.

Cosas para hacer prototipos

  • Arquitectura .
  • Nueva funcionalidad en un sistema existente.
  • Estructura o contenido de datos externos.
  • Herramientas de terceros o de sus componentes.
  • Problemas de rendimiento.
  • Diseño de la interfaz del usuario.

Preguntas sobre la arquitectura 

¿Están bien definidas las responsabilidades? ¿Están bien definidas las colaboraciones? ¿Está minimizado el acoplamiento? ¿Puedes identificar posibles duplicidades? ¿Son las definiciones y las limitaciones de interfaz? ¿Se puede acceder a los módulos necesarios de datos cuando sea necesario?

 Lista de verificación sobre la depuración

  • ¿Es el problema reportado un resultado directo de un error subyacente o es sólo un síntoma?
  • ¿Está el bug realmente en el compilador? ¿está en el S.O.? ¿ó está en tu código?
  • Si le explicas este problema en detalle a un compañero de trabajo ¿qué le dirías?
  • Si el código sospechoso pasa sus tests unitarios, son dichos tests suficientes? Qué pasa si corres los tests unitarios con estos datos?
  • Existe este mismo error en cualquier parte del sistema cuando se dan las mismas condiciones que producen dicho error?

Law of Demeter para funciones

Un método de un objeto sólo debe llamar a métodos que pertenezcan a:
  • Él mismo
  • Cualquier parámetro que se le pase
  • Los objetos que crea
  • Objetos componentes

Cómo programar deliberadamente

  • Estar atento a lo que estás haciendo.
  • No programes con los ojos vendados.
  • Procede siempre en base a un plan.
  • Confía sólo en las cosas confiables.
  • Documenta tus suposiciones.
  • Prueba las hipótesis, así como el código.
  • Siempre da prioridad a tu esfuerzo.
  • No seas esclavo de la historia

Cuando refactorizar

  • Cuando descubres una violación del principio DRY.
  • Encuentras cosas que pueden ser más ortogonales.
  • Tu conocimiento mejora.
  • Las necesidades evolucionan.
  • Es necesario mejorar el rendimiento.

Cortar el Nudo Gordiano

Cuando solucionar un problema parece imposible, pregúntate:
  • ¿Hay una forma más fácil?
  • ¿Estoy resolviendo el problema?
  • ¿Por qué es esto un problema?
  • ¿Qué lo hace tan difícil de solucionar?
  • ¿Tengo que hacerlo de esta manera?
  • ¿Se tiene que hacer por fuerza?

Aspectos de las pruebas

  • Prueba unitaria
  • Prueba de integración
  • Validación y verificación
  • Agotamiento de recursos, errores y recuperación.
  • Realización de pruebas
  • Pruebas de usabilidad
  • Prueba de las propias pruebas