No puedo escribir código limpio, no importa cuánto lo intente. ¿Qué tengo que hacer?

A2A.

Sin ver su código es imposible saber y abordar todos los problemas. Después de todo, las empresas se ven obligadas a gastar muchos recursos en entrevistar personalmente a los candidatos antes de contratarlos.

Aquí hay algunos consejos genéricos:

  1. No lea la declaración del problema o los requisitos e inmediatamente comience a pinchar el código. Casi siempre es contraproducente. Pase tiempo de calidad diseñando, corrigiendo, analizando y embelleciendo su algoritmo antes de codificar.
  2. Las revisiones de diseño son más importantes que las revisiones de código. Los errores en el diseño pueden causar un tiempo de inactividad grave, vergüenza y un reinicio del esfuerzo de desarrollo y prueba. Los errores en el código se pueden identificar y corregir de forma relativamente sencilla.
  3. La programación orientada a objetos, los principios de diseño y los patrones de diseño básicos no son opcionales. Debe conocerlos y aplicarlos sin importar cuán pequeño se sienta el proyecto. Recuerda, solo vas a ingresar más código en la línea. Mantenga las interacciones entre los objetos limpios y hasta el punto. Por ejemplo:
    1. Se le debe pedir al lechero que entregue solo leche (pero no flores) a la dirección de su casa (pero no a la dirección de la oficina) por la mañana (pero no por la tarde).
    2. El lechero no debe depender de (y no debe saber) la marca de su refrigerador. Mañana, si cambia el refrigerador o la ubicación de la oficina, no tiene que decírselo a su lechero.
    3. Si va a viajar al extranjero durante una semana, todos los “objetos” que visiten su casa, incluido el lechero, deben ser notificados de antemano.
  4. El código debe dividirse en tantas bibliotecas, clases y funciones simples y reutilizables como sea posible. Nómbrelos apropiadamente. Asegúrese de que hagan una y solo una cosa y que no haya duplicación de nada.
  5. Si no puede comunicar lo que hace cada una de sus clases o funciones en unas pocas oraciones a un ser humano, es poco probable que logre comunicar lo mismo a una computadora tonta.
  6. Las computadoras no hacen lo que tú quieres que hagan. Sólo hacen lo que les dices que hagan. Por lo tanto, la carga de la comunicación recae en usted. Conoce tu lenguaje de programación muy bien, incluyendo todos sus detalles intrincados. Evite usar construcciones erróneas incluso si el lenguaje las admite (como múltiples ++ y – en una expresión).

¡Felicidades! Quieres escribir código limpio y reconoces el código de espagueti. Ese es un gran paso. Algunas personas van décadas sin llegar tan lejos.

Aquí hay algunos pasos para ayudarlo a escribir un código más limpio. Cada paso proporciona beneficios incrementales. Es indoloro.

Paso 1: establece y sigue algunas reglas rígidas para ti.

Ciertos principios nos ayudan a escribir código limpio y mantenible. Si te has familiarizado con esos principios y no te han ayudado, prueba las reglas. No lo digo porque creo que todos debemos seguir reglas rígidas todo el tiempo. Pero este enfoque quita la subjetividad. Usted establece sus propias reglas y luego su código las cumple o no.

Sólo algunos:

  • No permita que ningún método exceda las 15 líneas. Siempre.
  • Nunca repita cinco líneas de código. Si se repiten cinco líneas de código, ponlas en su propio método.
  • Nunca escriba una clase, método o nombre de variable que no conste de una o más palabras completas que describan para qué sirve. Si su variable de bucle se llama i , cámbiela al índice. No dejes que te paralice. Dale un mal nombre y cámbiala más tarde. Pero hazlo descriptivo.

Si haces esas tres cosas, verás una mejora. Es 100% garantizado. Probablemente querrás codificar esas reglas rígidas por el resto de tu vida, y querrás que todos los demás también lo hagan.

Paso 2 – Familiarizarse con los principios de SOLID.

No te asustes, no dije que te convirtieras en un experto. Averigüe qué son (Google “Principios SÓLIDOS para principiantes”.)

Luego, reserve los últimos cuatro y céntrese en el Principio S – Responsabilidad Única , porque es el más fácil de entender y brinda un beneficio inmediato. No tenga miedo de escribir muchas y muchas clases si su solución lo requiere.

Si alguna página web usa una jerga que no entiendes o diagramas que te confunden, sáltatela y ve a la siguiente. Tú no eres estúpido. Son demasiado complicados.

A medida que aprende más sobre los otros principios uno por uno, sígalos ya sea que entienda las razones o no. En la mayoría de los casos, los beneficios de seguirlos y las consecuencias de no seguirlos no son inmediatos. Puede que no entiendas por qué lo estás haciendo. Confía en ello y hazlo de todos modos. Algo simplemente “hará clic” y luego lo verás. Pasará.

Paso 3 – Intenta escribir algunas pruebas unitarias

Sólo confía en mí en esto. Es posible que no vea ninguna conexión inmediata entre las pruebas unitarias y el código limpio. Pero es un circuito de retroalimentación de causa y efecto. Las pruebas unitarias fomentan el código limpio, y el código limpio es más fácil de realizar una prueba unitaria. Es posible exagerar las pruebas unitarias. Pero si alguien alguna vez te dice que no es importante huir, llama a la policía y nunca escuches nada de lo que te digan nunca más.

Aquí está mi propia prueba de unidad – Hola página mundial.

También, busque un libro llamado Code Complete, 2nd Edition. Ojalá lo hubiera sabido cuando empecé.

Encuentre un mentor : el mundo del software es grande y hay muchas cosas que puede encontrar en Internet al respecto, para ser sincero, hay demasiado y es difícil saber por dónde empezar. Encuentre a alguien que haya estado en la industria por un tiempo y que se mantenga actualizado. Define un plan con esta persona sobre lo que debes estudiar

Haga que revisen su código : por lo general, hay muchas maneras de lograr algo y muchas formas muy malas. Si bien Internet está lleno de grandes recursos, está lejos de ser perfecto. Asegúrese de pedirle a su mentor que revise su trabajo de vez en cuando, para que no esté aprendiendo de la manera incorrecta.

Practique con algo significativo : los siguientes tutoriales tienden a ser molestos, una vez que se sienta lo suficientemente cómodo con una tecnología, intente idear una idea de proyecto personal en la que tenga que usar lo que esté aprendiendo. Eso te ayudará enormemente a mantenerte motivado y a estar orgulloso de ti mismo. Recuerde que PUEDE HACERLO, es una cuestión de tiempo y perseverancia, pero el camino puede ser largo. Para ser un gran ingeniero de software, necesitarás 3 habilidades:

1. Conocimiento de la pila completa : las aplicaciones de software son sistemas complicados compuestos de muchas tecnologías y partes: frontend, backend, base de datos, servidor web y red. Por ejemplo: cambiar una consulta en el frontend afectará a la base de datos si el desarrollador no tiene idea de cómo funcionan las bases de datos, la consulta podría hacer que el sitio no funcione. Algoritmo y estructura de datos Programación de alto nivel (lenguajes de programación de objetos orientados) Administración del sistema y un poco de conexión en red. Con esto, un ingeniero de software podrá navegar por casi cualquier sistema / aplicación y podrá tomar una decisión de ingeniería bien pensada.

2. Poder aprender solo: los conceptos básicos del software rara vez cambian, pero las herramientas que utiliza la industria cambian constantemente. La industria del software es probablemente una de las que cambian más rápidamente, por eso necesita actualizar constantemente la aplicación de su teléfono inteligente y que sus sitios web favoritos traigan constantemente una mejor experiencia y características. En este contexto, los ingenieros de software necesitan constantemente evaluar y quizás aprender nuevas herramientas que les ayudarán a hacer su aplicación más rápida, mejor y más confiable. Los nuevos lenguajes de programación y las bibliotecas vienen constantemente y uno no puede regresar a la universidad cada vez que surja una nueva tecnología. Los mejores ingenieros de software son los que pueden mantenerse al día con las últimas tendencias. Por eso es fundamental que puedas aprender por ti mismo.

3. Habilidades blandas : a menos que esté dispuesto a trabajar solo, podría ser la habilidad más importante. Hay un buen libro sobre esto, “Cómo ganar amigos e influir en las personas” porque este libro es muy importante para aprender a ser un ser humano exitoso. No se puede imaginar cómo el ser amable con las personas y ayudarlas a hacer su trabajo les traerá mucho más. Recuerda que para una empresa, si haces bien tu trabajo, eres un 1X. Pero digamos que también está ayudando a 10 personas a hacer bien su trabajo, entonces usted es un 11X y ese es el tipo de personas que necesitan las empresas exitosas. Si puede obtener estas 3 cosas, será un programador increíble y todos querrán contratarlo. Esto es lo que hacemos en la escuela de Holberton. http: //www.holbertonschool.com ¡Buena suerte en su camino para convertirse en un gran programador!

Aquí hay algo que hice una vez que puede ayudar.

Fui el líder de software en un proceso automatizado que usaba un robot Staubli, un alimentador de tazones, una mesa giratoria accionada por Delta Tau, un sistema de visión y cientos de miles de pequeñas cuentas con etiquetas RFID utilizadas en el campo farmacéutico llamado ciencia combinatoria. Digamos que fue bastante jodidamente complicado. Necesitaba que mi equipo tuviera una dirección clara. ¿Cómo trabajamos todos en diferentes subconjuntos mientras retóricamente hablando, cantamos el mismo himnario?

Yo mismo escribí el código para todo el sistema en 2 días y noches. Bueno en realidad no. Escribí el psuedocode definido a la ligera que mi equipo llamó “Magic Basic”. Tenía suficientes detalles para asegurar que todos los métodos y objetos de datos estuvieran bien definidos. Todo lo relacionado con la base de datos estaba bien definido. Después de todo, ¿qué sucede cuando alguien tira del enchufe en el El proceso de la mitad de una semana de uso de cientos de miles de cuentas a $ 5 por barril que no se puede reutilizar? Cada sección se desglosó y hubo suficiente “código” para entender lo que quería decir. El equipo hizo un trabajo increíble para que hiciera lo que nosotros dijo: no es lo que quise decir. Este fue el primer proyecto en mi breve permanencia allí que llegó temprano y dentro del presupuesto: una historia real.

La moraleja de esta historia es escribir una especificación que funcione para usted (la mía es “Magic Basic”). Divida todo en subconjuntos incluso si es solo un código. Luego detalle cada subconjunto. Póngalos todos juntos y viola: una aplicación orientada a objetos fácil de seguir en la vista de 30,000 pies.

La mejor de las suertes: todos comenzamos en algún lugar y tuvimos nuestros propios desafíos. Sé un ganador: nunca dejes que un proyecto te atrape en el suelo. Rasca y garra tu camino hacia el éxito y te alegrarás de haberlo hecho.

  1. Escribir código usando solo valores. Mutar sin variables.
  2. Asegúrate de que todas las funciones que escribas sean referencialmente transparentes. Es decir, dado un conjunto particular de valores de entrada, esa función debe devolver el mismo valor (incluidos los mismos cambios en el estado del sistema) para cada invocación.

Eso es.

El resultado de seguir estas dos reglas es que su código será fácil de entender, porque no requerirá un seguimiento mental del estado, y fácil de refactorizar, porque cada función que escriba estará compuesta de funciones más pequeñas que obedecen a las mismas propiedades. Dado que sus funciones serán referencialmente transparentes, los efectos secundarios deben encapsularse como valores, lo que los hace fáciles de identificar y manipular.

Es probable que no esté trabajando en un lenguaje que haga un buen trabajo en este tipo de programación, pero está bien; Es posible básicamente en cualquier idioma. Sin embargo, su mayor desafío será aprender a escribir código en este estilo, para empezar. Para este propósito, recomiendo aprender Haskell, ya que es probablemente el idioma más accesible que admite escribir código en este estilo; luego puede tomar lo que aprendió allí y aplicarlo a lo que use en su trabajo diario.

Tendrás que resolver la pereza por tu cuenta. Para mí, un buen estímulo es “Si sigo siendo perezoso, perderé mi trabajo”.

Hay algunos pasos que puede seguir para simplificar su código:

  • Refactorizar funciones complejas en simples. Cada función puede tener un nivel de anidamiento como máximo. Ejemplo:

// Original

función foo (x, y) {
mientras (x> 0) {
while (y> 0) {
y–;
}
X-;
}
}

// Refactor

barra de funciones (y) {
while (y> 0) {
y–;
}
devuelve y;
}

función foo (x, y) {
mientras (x> 0) {
y = barra (y);
X-;
}
}

  • Mantenga su código seco. Cada vez que te das cuenta de que te has repetido, mueve el código repetido a una función separada:

// Original

función foo (x, n) {
si (x> 100) {
n = n + x;
n = n / 2;
devuelve n;
}
}

barra de funciones (y, n) {
si (y <20 && n == 5) {
n = n + y;
n = n * 2; // ¡No es una repetición exacta!
devuelve n;
}
}

// Refactor

función baz (value1, value2, shouldDivide) {
dejar total = valor1 + valor2;
volver debería dividir? total / 2: total * 2;
}

función foo (x, n) {
si (x> 100) {
devuelve baz (x, n, verdadero);
}
}

barra de funciones (y, n) {
si (y <20 && n == 5) {
devuelve baz (y, n);
}
}

Nota: es normal repetir el código. Eso es parte del proceso. A menudo no sabes que tendrás que repetirlo al principio, por lo que inicialmente no lo haces para su propia función. Si solo existe foo (), tiene sentido poner el código que necesita dentro. Pero, más adelante, cuando escriba bar () y se encuentre repitiendo algo de código de foo (), se dará cuenta de que debe refactorizar.

También soy una persona perezosa, así que tengo que luchar contra la necesidad de dejar repeticiones en mi código, especialmente si es solo un par de líneas de cosas que no están SECAS, como en el ejemplo anterior. Simplemente tengo una regla dura para mí. Cualquier código que se registre debe estar SECO.

  • Trabajo sobre nombres. Una buena denominación suele ser la clave para (a) hacer que su código sea legible y (b) saber si tiene un buen conocimiento de lo que está programando. Cuando me doy cuenta de que no puedo pensar en un buen nombre para una función, clase o archivo, eso generalmente significa que estoy confundido acerca de lo que está haciendo. Los buenos nombres deben describir exactamente lo que hace el código nombrado. (No cómo lo está haciendo. Lo que está haciendo.)

    Cuando puedo pensar en un buen nombre, pero es un nombre largo y compuesto, como calculadatosAndDisplayIt (), eso suele ser un signo que necesito para refactorizarlo en múltiples funciones o clases: calcularData () y displayData ().

    Tenga cuidado con los nombres vagos como DataManager y, como en mi ejemplo, arriba, calculaData (). ¿Qué está haciendo exactamente DataManager? ¿Qué tipo de cálculo está ocurriendo?

    Muy a menudo tengo que renombrar funciones, clases y archivos. No tengas miedo de hacer esto. No seas perezoso al respecto. Si lo que hace el código cambia, es posible que necesite un nuevo nombre para describirlo. (Por supuesto, la excepción es el código API. No se puede simplemente cambiar el nombre de los módulos utilizados por otro código).

  • Libere su código de valores “mágicos”:

// Malo

si (x <23789) {

}

// Bueno

const COST = 23789;

si (x
}

No debes seguir servilmente ninguna de las reglas que he sugerido. Si tiene sentido tener múltiples niveles de anidamiento en una función, o si calcularData () realmente es la mejor descripción, está bien. Simplemente haga una elección inteligente, teniendo en cuenta la legibilidad y la capacidad de mantenimiento.

Aquí hay algunas reglas de oro.

  1. Si una función es más larga que diez líneas, desconfíe. Diez es arbitrario. Es el número que uso. Si escribo una función que es más larga que eso, no la refactorizo ​​automáticamente. Pero verifico si hay alguna manera de simplificarlo. Las funciones más largas son difíciles de razonar.
  2. Si tiene que desplazarse en un archivo para leer todo el código, desconfíe. Mantener módulos tan pequeños a menudo es imposible, pero al menos intento comenzar a buscar códigos demasiado complejos cuando mis archivos se vuelven más largos de lo que puedo colocar en una pantalla.

Esto ha sido solo una descripción general con algunos consejos. Hay libros completos sobre refactorización que puedes y debes leer. Pero creo que si sigues las reglas anteriores, recorrerás un largo camino para hacer que tu código sea legible y mantenible, y serás menos afectado en las revisiones de códigos.

ACTUALIZACIÓN : El usuario-9780881916180275396 y yo tuvimos una buena discusión en los comentarios, y me gustaría resumirlo aquí. Su (muy buena) preocupación es que, si solo usamos un nivel de anidamiento en las funciones, los lectores del código tendrán que desplazarse en busca de las funciones llamadas dentro del anidado de un nivel:

función foo (x) {
mientras (x <1) {
barra (x)
}
}

Para entender lo que está pasando, debes buscar la barra (). Estoy de acuerdo en que eso no es lo ideal. Una mala solución es explicar con comentarios.

función foo (x) {
mientras (x <1) {
// barra todos los Xs
barra (x)
}
}

No soy un fanático de los comentarios, a menos que sea absolutamente necesario, porque es increíblemente fácil cambiar el código que está comentando y olvidarse de actualizar los comentarios, y las pruebas unitarias no le dirán que lo ha hecho.

función foo (x) {
mientras (x <1) {
// barra todos los Xs
qux (x)
}
}

La mejor solución es combinar dos de mis sugerencias: anidamiento superficial y buena denominación:

función foo (x) {
mientras (x <1) {
writeToLog (x)
}
}

Como han dicho otros, la pereza es a menudo una virtud, si la combinas con un poco de cerebro.

Cuando se le asigna la tarea de cortar un árbol, tiene dos opciones:

  1. Comience de inmediato a golpearlo con sus propias manos, tómese días para terminar el trabajo, tenga un lío de madera al final
  2. Pare a pensar, construya una herramienta para cortar árboles, termine en dos días, tenga un tronco cortado fino al final

Aquellos que eligen la opción 2 son un tipo de personas perezosas (el tipo para el que pensar durante una hora no es tan difícil como trabajar durante días).

Usa tu pereza a tu favor.

Sobre el código de reescritura : nadie crea código que no necesite reescritura, nunca. Incluso el mejor código puede ser un poco mejor, volverse obsoleto, chocar con nuevas especificaciones, incurrir en errores increíbles e inexplicables de la plataforma de su elección.

Dicho esto, si regularmente no cumple con un requisito mínimo, obviamente es un problema para su productividad y me imagino que está preguntando cómo obtener un código más limpio antes sin tener que volver a escribir más tarde. Aprender de sus errores es necesario, pero tal vez no sea suficiente. Tal vez tengas que encontrar la mejor manera de codificar.

Algunas sugerencias

  1. no ignore las advertencias que le está dando su IDE y corríjalas de inmediato
  2. Dividir grandes problemas en problemas más pequeños.
  3. Intenta detectar patrones, adaptar y reutilizar código.
  4. No tenga miedo de refactorizar o eliminar el código que acaba de escribir
  5. use herramientas que analizan automáticamente el código (como SonarQube), configuradas adecuadamente para no molestarlo con problemas triviales
  6. pruebe el desarrollo basado en pruebas si es aplicable en su caso: ayuda a identificar y crear unidades funcionales autónomas en su código, y también obtiene una depuración gratuita
  7. al analizar el problema y evaluar las posibles soluciones, escriba y pese todas las consecuencias de cada solución
  8. Piensa antes de hacerlo, independientemente del tiempo que tengas disponible: harás menos trabajo, no más

Debes comenzar a escribir muchos códigos y revisar el código de otras personas.

Cuanto más código escriba y más vea lo que escriben los demás, más rápido aprenderá a escribir código pequeño pero fácil de mantener. Le sugiero que comience este viaje creando una cuenta de stackoverflow y comience a responder preguntas . Los programadores profesionales verán tus respuestas y ofrecerán críticas constructivas que te ayudarán a crecer más rápido. Además, cuando escriba el código de hobby, póngalo en la vista de código y, una vez más, muchos buenos programadores revisarán minuciosamente su código y su aprendizaje aumentará. También intente hacer lo mismo con otras personas que publiquen su código allí.

La cuestión es que las “mejores soluciones” no se revelan hasta que hayas escrito una buena solución , y las mejores soluciones son tan raras como los Pokémon más raros. Esfuércese por escribir una solución, luego intente esforzarse aún más para encontrar una solución mejor, solo entonces se presentarán al inicio y ahora se le deja a usted perseguir la esquiva voluntad (o’-the-wisp, las mejores soluciones).

La pereza es una virtud cuando se usa apropiadamente para facilitar su trabajo.

El software, como muchas otras cosas, se basa en tener una buena base, un esqueleto, una “arquitectura” o lo que se quiera llamar.

En software “bueno” generalmente significa simple , porque es un hecho de la vida en la ingeniería de software que necesitará depurar lo que escribió antes o después, y luego estará muy feliz de haber escrito un código simple y fácil de leer. .

Una buena base es importante para todas las partes de un sistema de software, desde funciones / métodos individuales hasta cómo los diferentes componentes de un sistema interactúan o incluso cómo interactúan los diferentes sistemas.

Trate de entender realmente el problema central que está a punto de resolver. Experimenta hasta que lo hagas escribiendo fragmentos de código cortos. No importa si este código experimental es feo, ya que el objetivo principal es entender lo que vas a hacer.

Una vez que haya entendido “lo suficiente” sobre su problema, escriba su primera versión real del código o continúe desde la última versión experimental si está satisfecho con él.

Si no entiende lo que debe hacer, ¡pida ayuda a sus compañeros! Las personas que te dan malas críticas de código probablemente estarán encantadas de ayudarte. Si no es así, es probable que haya problemas culturales graves en el trabajo.

“La pereza es una virtud” es un dicho bastante común en la ingeniería de software , ya que es bueno ser perezoso si resulta en escribir el menor código posible. ¡Cuanto menos código tenga, más fácil será entenderlo y mantenerlo!

La pereza también puede significar usar siempre el mismo enfoque en lugar de intentar reinventar la rueda cada vez que te enfrentas a un nuevo problema. Eso es algo bueno, siempre que su enfoque sea bueno (suficiente).

Finalmente, si da algunos ejemplos de lo que quiere decir con pereza y algunos ejemplos de qué tipo de malas críticas ha recibido, probablemente obtendrá ayuda y sugerencias más concretas.

Identifique los conceptos básicos de dominio que su aplicación necesita para modelar, defínalos en detalle e implementelos de manera muy limpia. Se adhieren a su separación después de algunas iteraciones de refinamiento, incluso si se siente un poco artificial. Todo lo demás debe basarse en la biblioteca que implementa este conjunto de conceptos básicos. Utilice bibliotecas para conceptos laterales de los que no tiene una comprensión profunda (es decir, a partir del trabajo de expertos en dominios).

En el caso de conceptos de dominio cruzado, limite la confusión / el desorden / la confusión. La mayor fuente de desorden de códigos son los conceptos confusos y la implementación inconsistente de los conceptos centrales. Sea diligente en desarrollar y utilizar sus propias bibliotecas centrales. Si no, el código pronto se dispersará con re-implementaciones inconsistentes, incompletas y descuidadas de los mismos conceptos. Es posible que no los reconozca como tales, pero a menudo son las mismas cosas en diferentes formas inconsistentes.

Una vez que haces eso, los lenguajes, las bibliotecas y los marcos se presentan.

En programación siempre hay una herramienta para X. Y para ti tengo dos:

  1. Formato de código automático “fmt”: vaya a su código
  2. Linters: ¿Qué es “Linting”?

Lo que básicamente hacen es forzar una sola forma de escribir código. Los linters le mostrarán algunos errores y advertencias sobre las cosas que escribe, fmts se autofijarán automáticamente para usted. De esa manera el código estará más limpio.

Mike y Bob tienen respuestas útiles, pero tal vez falten el principio general involucrado. Aquí está mi historia de guerra y la lección que aprendí de ella.

En 1988, fui contratado, en mi segundo trabajo profesional, por un contratista de servicios de defensa en White Sands Missile Range para reemplazar a dos programadores que renunciaron después de haber intentado sin éxito durante varios meses preparar un sistema informático para una prueba. Heredé una especificación del gobierno pero no un código utilizable. Ah, y la prueba fue en 6 semanas. Reconocí que tenía que usar un enfoque extremadamente disciplinado para cumplir con el plazo “imposible”.

Escogí una metodología, Diagramas de Nassi-Schneiderman, y una herramienta, MacDraw, para construir los Diagramas de NS. Utilicé un enfoque de refinamiento sucesivo, colocando bloques (bucles, condicionales, procedimientos, etc.) que parecían hacer avanzar la solución pero sin detalles de nivel de codificación.

Finalmente, después de muchas iteraciones y siguiendo algunas ideas sin salida, bajé al nivel de detalle en el que mis diagramas NS podían traducirse directamente en código. Eso llevó un par de semanas. Me tomó un par de semanas más escribir el código y una semana de depuración porque las herramientas de ese día eran mucho más primitivas que las que tenemos ahora. En medio de todo esto, me tomé una semana libre para asistir a una convención (MacExpo San Francisco). Así que hice mi fecha límite. Woo hoo!

Hoy en día, con las mejores herramientas que tenemos disponibles y casi 30 años de experiencia , pasaría no más de un día en diseño y una semana en codificación y pruebas para una aplicación de soporte de prueba única. Para un sistema de mantenimiento a largo plazo, habría un código de prueba (love gtest!) Y comentarios de Doxygen a medida que codifico el proyecto , para documentar el sistema para aquellos que vienen después para mantenerlo.

¿Cuál es la lección general que hay que aprender aquí? La ingeniería de software requiere un estilo de desarrollo disciplinado y orientado al proceso. El estilo de “mejores prácticas” es:

  1. Comience con el diseño, no con la codificación, utilizando cualquier herramienta que funcione para usted (incluso el uso de MS Word como un esquema para algunas personas). o use las herramientas o plantillas que su tienda requiera.
  2. Utilice iteraciones sucesivas en el diseño para pasar de un diseño de alto nivel a una especificación detallada. Mantener el documento de diseño de alto nivel como referencia.
  3. Comienza el ciclo de codificación y prueba. Si desea o está obligado a utilizar Test Driven Design u otras técnicas de ingeniería de software útiles, tenga en cuenta al hacer su diseño, ¡pero Design First!
  4. Ajuste el diseño o especificación según sea necesario. Si tiene un problema menor, esto no debería ser necesario, pero ninguna asignación grande (de varios meses) obtendrá un diseño perfecto en el primer intento.

El razonamiento detrás de este enfoque es que la codificación, especialmente para programadores junior (aproximadamente, los primeros 5 años), está demasiado orientada a los detalles para permitirle concentrarse en la estructura y el diseño de su solución. Los delineadores (o los últimos MacDraw, OmniGrafle o Visio, etc.) no mostrarán errores de sintaxis, etc., a medida que escribe, lo que lo distrae de la tarea de diseño.

La mejor manera de producir código limpio es refactorizar y simplificar . Se trata de novelistas análogos que hacen múltiples borradores y reescrituras.

Los libros no están escritos, son reescritos.
– Michael Crichton, autor de best sellers.

La reescritura / refactorización permite el descubrimiento y profundiza su comprensión del problema. Tres consejos profesionales que me han ayudado a escribir un código más limpio:

  1. Hackee una solución rápida y sucia para una característica particular en una rama con púas . El pico ayudará a profundizar su comprensión de los requisitos de la función y permitirá el descubrimiento. También te da algo que funciona (es decir, no es bonito, pero funciona). Si no fuera un artesano que se preocupara por el producto, enviaría este trabajo de mala calidad como una solicitud de extracción y lo llamaría un día.
  2. Ten cuidado con tu pincho de trabajo. Cortar una nueva rama de función. Comenzar de nuevo. Aplique la esencia de lo que aprendió en su punta, pero esta vez, construya un arnés de prueba (o arneses de prueba) alrededor de los métodos. Utilice el desarrollo puro test-first , test-test (TDD). Permitir más descubrimiento . Centrarse en las mejoras.
  3. Examine sus diferencias en una herramienta de comparación de lado a lado para que pueda revisar cuidadosamente el conjunto de cambios propuesto. Imagina que estás revisando la solicitud de extracción de alguien más. ¿Las variables son nombradas apropiadamente? ¿Hay un formato consistente? ¿Se cubre cada método con una prueba de unidad significativa? ¿Se cumplen los criterios de aceptación ? ¿Cómo se puede simplificar el código? ¿Cómo puede hacerse el código más legible? ¿Es el código autoexplicativo para que los comentarios sean superfluos?

No siempre sigo estos consejos, pero cuando lo hago, mi código es invariablemente mejor.

Estoy de acuerdo con todas las respuestas anteriores, pero quiero reducirlo a un concepto que todos tocan: diseñar primero, codificar segundo.

En mi experiencia, el código de espagueti es un código que ha crecido orgánicamente. Viene de un proceso de pensamiento que dice algo como “Necesito hacer esto”, así que lo haces, entonces piensas que “ahora necesito hacer eso”, así que también lo haces, entonces te das cuenta de que “oh, eso afecta esto”, así que Agrega más código para manejar ese caso. Repita hasta que termine, excepto que nunca habrá terminado porque las cosas están tan enredadas.

Si bien las herramientas de software son útiles más adelante para solidificar y documentar el diseño, siempre comienzo utilizando lápiz y papel o, mejor aún, una pizarra. El costo de explorar el problema y determinar las relaciones se vuelve bastante bajo cuando puede anotar conceptos en cualquier forma que desee en una pizarra y luego borrar, modificar o corregir según sea necesario.

Una de mis citas favoritas de Lincoln es “Si me dieran 8 horas para cortar un árbol, me pasaría 6 horas afilando el hacha”. La preparación es el primer paso importante, no te lo saltes.

Escribe el código malo primero, luego hazlo mejor.

Lee a Martin Fowler y Bub Martin cuando te acuestes. Entonces comienza a refactorizar tu código malo. Divida las cosas en funciones y módulos y objetos y paquetes. Cuando esté tentado a copiar y pegar el código, resuma.

También estudie patrones de diseño, al menos, estudiar patrones de diseño le dará un conjunto de plantillas e ideas que mejorarán todo su código.

A continuación, comience a practicar el desarrollo guiado por pruebas, que lo ayudará a captar lo que está tratando de hacer. Rechaza la tentación de solo reescribir todo el código, en lugar de ello, encuentra formas de mejorar el código que estás escribiendo.

He visto algunas buenas respuestas a tu pregunta con mucha verborrea. Pero creo que la respuesta de tu pregunta es bastante simple. Sí, esa es la palabra clave. SIMPLIFICAR. Esto es lo que hago:

  1. Crear una especificación funcional primero. Si no sabes cómo hacer una especificación funcional que leer sobre especificación funcional por Joel Spolsky. Esto resolverá el 80% de su problema.
  2. Divide y conquista: asegúrate siempre de modularizar el código. Ayudará inmensamente.
  3. Por último, pero no menos importante, codifique una cosa a la vez. ¿Cómo vas a comer un elefante? 🙂 Un pequeño bocado a la vez.

La práctica habitual te hace un mejor programador. La experiencia no tiene precio. Si lo intenta y aún no lo logra, no importa cuánto lo intente y por cuánto tiempo lo intente, es posible que necesite una mejor dirección. Mira otro código para ver cómo otros desarrolladores resuelven problemas. Si hay una sección que no entiendes, pregunta qué hace. Si estás confundido por qué el desarrollador x hizo algo de cierta manera, pregúntales. Después de un tiempo, sus soluciones tendrán sentido para usted y usted comenzará a ver el problema como lo hacen ellos, y creará soluciones similares. Esta es una de las cosas que más lamento en mi carrera. Cuando empecé, no conocía a otros desarrolladores y la mayoría trabajaba de forma aislada. Fallé muchas veces, cometí muchos errores antes de darme cuenta de que sería mejor seguir a los demás. Otra cosa que recordar es que la programación puede ser difícil, independientemente de lo que otros le puedan decir. Si alguien se está recuperando de problemas, es probable que hayan resuelto problemas similares anteriormente, estén escribiendo código que no se pueda escalar, estén plagados de errores y vulnerabilidades de seguridad, o simplemente sean una persona muy inteligente que sobresalga en cualquier cosa que hagan. . Pero para la mayoría de los muggles, luchamos por encontrar la solución correcta. A veces tenemos que experimentar primero antes de tenerlo bien. Incluso los grandes desarrolladores cometen errores. Algo que me ha funcionado es que soy implacable. Quiero escribir el mejor código posible, por lo que siempre estaré pensando en el futuro de cómo podría verse este código para alguien que no lo escribió. ¿Puedo hacer la función más pequeña y más precisa? Si la función necesita más de una oración para describir lo que hace, ¿quizás necesita hacer menos? Tal vez necesita un nombre mejor? También disfruto la fase de planificación. Me encanta trazar los diferentes componentes y cómo se comunicarán entre sí. Miro para ver si puedo usar algún patrón de diseño en particular. Me encanta mencionar a mi equipo en nuestra revisión diaria o en las revisiones de código por las que tomo un cierto enfoque, porque defender su solución es una excelente manera de determinar si es demasiado complicado o tiene sentido. Si te encanta la programación, hay muchas posibilidades de que tengas éxito. Es posible que necesites una mejor dirección.

Sigue intentando Entiende lo que hiciste mal. Arreglarlo la próxima vez.

¡Sólo escribe inglés!

No complique demasiado las cosas y solo escriba un comentario sobre por qué lo hizo, hace que todo sea más fácil