¿Deberíamos fomentar los estilos de codificación a favor de la autonomía del desarrollador, o desalentarlo a favor de la coherencia?

15

Un desarrollador escribe if/elsebloques con declaraciones de código de una línea como:

if (condition)
   // Do this one-line code
else
   // Do this one-line code

Otro usa llaves para todos:

if (condition) 
{
   // Do this one-line code
}
else
{
   // Do this one-line code
}

Un desarrollador primero crea una instancia de un objeto, luego lo usa:

HelperClass helper = new HelperClass();
helper.DoSomething();

Otro desarrollador crea instancias y usa el objeto en una línea:

new HelperClass().DoSomething();

Un desarrollador es más fácil con matrices y forbucles:

string[] ordinals = new string[] {'First', 'Second', 'Third'};
for (i = 0; i < ordinals.Length; i++)
{
    // Do something
}

Otro escribe:

List<string> ordinals = new List<string>() {'First', 'Second', 'Third'};
foreach (string ordinal in ordinals)
{
    // Do something
}

Estoy seguro de que sabes de lo que estoy hablando. Lo llamo estilo de codificación (porque no sé cómo se llama). Pero como sea que lo llamemos, ¿es bueno o malo? ¿Alentarlo tiene un efecto de mayor productividad de los desarrolladores? ¿Deberíamos pedirles a los desarrolladores que intenten escribir código de la forma en que les decimos, para que todo el sistema sea coherente con el estilo?

Saeed Neamati
fuente
1
En realidad, estaba viniendo aquí para hacer una pregunta muy similar en este momento: cuando las herramientas de formateo de código automático están disponibles y son convenientes, ¿es más importante que esas herramientas no se ejecuten (y conserven estilos personales inconsistentes) o que se aplique un estilo?
esponjoso
El estilo consistente facilita la lectura del código, por lo tanto, use un estilo consistente. En sus ejemplos, el más fácil de leer es 2, 1, 2. Aunque el último caso es diferente. En aplicaciones críticas de rendimiento, el bucle for es más rápido cuando se itera sobre listas. El rendimiento es idéntico iterando sobre matrices. Y en todos los casos, use en varlugar del nombre de tipo completo.
Stephen

Respuestas:

19

Un documento de estándares de codificación es útil. Es más útil cuando es lo suficientemente corto como para que alguien pueda recordar todo sin demasiados problemas y cuando no causa demasiado dolor a nadie.

Cómo elige sangrar código en su organización, o poner en mayúscula los nombres, o implementar sus bucles, o comentar su código no importa tanto; la parte útil es lograr que todos escriban código que se parezca a los demás.

  • Evita tener que pasar un minuto recalibrando sus expectativas de dónde deberían estar los aparatos ortopédicos y tal cada vez que mira el código de otra persona.
  • Evita tener varios estilos diferentes de código en el mismo archivo.
  • Quizás lo más importante es que tener un estándar escrito evita los argumentos sobre las prácticas de codificación durante las revisiones de código.

Una vez más, cuáles son los estándares no importan tanto como tener algún tipo de estándar simple y directo. Por lo tanto, ponga a todos sus desarrolladores en una sala y déjelos discutir sobre cuáles deberían ser los estándares. Esta reunión podría continuar indefinidamente, por lo que las reglas son:

  • Cualquier cosa que no se decida al final de la reunión será decidida por el gerente.
  • La reunión finalizará después de dos horas, o cuando alguien comience a gritar o llorar, lo que ocurra primero.
  • Todo el estándar se ajustará (¡en un tamaño de letra razonable!) En una hoja o dos de papel, a doble cara solo si es absolutamente necesario.

Considera adoptar a alguien | de los demás | estándares, ya sea como punto de partida para su propia reunión de estándares de codificación, o como una forma de evitar la reunión por completo.

Una vez acordado, los desarrolladores deberían poder (y debería esperarse) controlarse a sí mismos. La desviación ocasional del estándar no debería ser un gran problema (e incluso podría ser justificable), pero la negativa negativa de abandonar algún estilo personal favorito en favor del estándar debería resultar en la reubicación inmediata a la oficina con las tuberías de agua con fugas, o lo que sea .

Demian Brecht señala las herramientas de pelusa. Estos son un complemento perfecto para un documento de estándares de codificación. Es simplemente bueno cumplir con los estándares de estilo de codificación ; Es importante cumplir con los estándares de codificación que se relacionan con prácticas peligrosas. Nadie más que el autor verificará que cada línea de código cumpla con el estándar de estilo, pero sin duda debería considerar incorporar una herramienta de pelusa en el flujo de trabajo de su equipo para detectar automáticamente posibles errores. Además, la herramienta en sí puede codificar las prácticas aceptadas para que no tenga que enumerarlas todas individualmente en los estándares de codificación; solo especifique la configuración de la herramienta.

Nota: La idea de "estándares de codificación" no es exclusiva de la programación. Los "estándares de codificación" se utilizan en muchos campos, a veces dentro de una organización, más a menudo en toda una industria o profesión. Algunos ejemplos:

En cada caso (y en muchos otros), un profesional competente podría entender fácilmente el "código" que no cumple con el estándar esperado. ¿Por qué tantas industrias persisten en escribir requisitos detallados para documentos que ni siquiera necesitan ser analizados por un compilador? Porque el estilo importa . La presentación de información en un estilo estándar permite al lector centrarse completamente en el contenido, agiliza la lectura y ayuda a la comprensión, y reduce los errores.

Caleb
fuente
1
Si agrega el uso de herramientas de linting a su publicación, eliminaré la mía y +1 la suya :)
Demian Brecht
@DemianBrecht, buena sugerencia, gracias. Se agregaron herramientas de pelusa para mejorar mi respuesta, pero creo que también deberías dejar la tuya.
Caleb
Pues bien entonces. +1 de todos modos :)
Demian Brecht
¡Y también a ti!
Caleb
+1 para la "... reubicación inmediata ..." ya que, según mi experiencia, tal comportamiento es consistente con las tendencias sociópatas y / o narcisistas, incompatible con los equipos de desarrollo de software.
mattnz
16

El estilo no importa.

Ahí lo dije.

Después de 30 años, y cientos de sitios de clientes, y el código de (estimando) 500 (o más) miembros del equipo durante esos años, descubrí que el estilo simplemente no importa.

Ponlo a trabajar, primero.

Haga que use un volumen óptimo de recursos (es decir, estructura de datos correcta, algoritmo correcto).

Alboroto sobre el "estilo" después de que todo lo demás se haya resuelto. Alboroto de "estilo" solo con herramientas, nunca manualmente.

S.Lott
fuente
2
¡Amén! Los estándares de codificación deben justificarse en términos de beneficios reales y la coherencia no es un beneficio real, sino un lujo.
JohnFx
12
Pero el estilo rara vez se trata de estilo. Se trata de evitar errores comunes.
Martin York
66
Pero ayuda a evitar '=' en lugar de '==' (no use la asignación dentro de la condición). Ayuda a evitar en if (t) { x;y;}lugar de if (t) x;y;(siempre use '{}' después de if). Prefiera el código const correct (es muy difícil agregar la corrección const en el código después de que se ha escrito. Use std :: cout / std :: cin not fprintf / scanf, es mucho más probable que los primeros causen errores. Use vectores en lugar de matrices (para ayudar a prevenir el desbordamiento)
Martin York
55
Obviamente, hacer que funcione es primordial. Pero solo porque funciona no significa que esté hecho. También necesita ser probado. Y luego revisado. Eso puede llevar unos días. Luego, durante años después, tiene que ser leído, entendido y mantenido. El código útil (¿por qué escribir cualquier otro tipo?) Se leerá muchas más veces de lo que está escrito, por lo que facilitar su lectura y comprensión mejora la productividad en el futuro. Usar un estilo consistente en toda la organización es una forma de ayudar en ese sentido.
Caleb
1
¿Qué pasa con la aplicación de herramientas de formateo automático? Eclipse y XCode hacen que sea muy fácil mantener el formato del código, pero uno de los ingenieros con los que trabajo se molesta mucho si alguien autoformata "su" código (es decir, el de la empresa) para que sea coherente con el resto de la base de código. El formateo es solo una pequeña parte del estilo, pero también es importante, especialmente para problemas como el anidamiento if / else y el flujo general del código (sin mencionar la legibilidad).
esponjoso
4

Hay estilos de codificación y hay olores de codificación. No fue una vez que encontré:

    if(debugCondition)
//         printf("DEBUG: state:%s at debugCondition\n",dbg_state());

    for(i=0; i<MAX;i++)
    {
       //some essential business logic
    }

Mi empleador anterior ha prohibido rigurosamente el uso de líneas if()múltiples sin aparatos ortopédicos. Se consideró un error tipo "hazlo de nuevo y estás despedido". Las construcciones permitidas fueron

     if(condition) break; 
     if(condition) continue; 
     if(condition) return; 
     if(condition) for()...; 

Esto resultó de un error como el que mostré arriba, que tardó un par de horas en detener la página principal del portal.

Hay cosas que debes hacer siempre. Como switch():

     case 1:
         something();
     break;
     case 2:
         something();
     return;
     case 3:
         something();
     continue;
     case 4:
     case 5:
         something();
     break;
     case 6:
         something();
     //fallthrough;
     case 7:
     ...

Mientras tanto, escribiendo:

     case 1:
         something();
     case 2:
         something();
     break;

sin cerrar un casecon //fallthroughse considera un error.

En general, existe el estándar de codificación, que son las pautas que pueden ignorarse, interpretarse creativamente o modificarse para las necesidades dadas. Y está la sección sobre "olores" y debe ser obedecida rigurosamente.

SF.
fuente
3

Crea consistencia con un buen diseño inicial. Lo que describe en la pregunta es nada menos que microgestión. Hago mucho desarrollo web. Por lo tanto, estoy a favor del desarrollo RESTful y CRUD expuesto como servicios. Esto garantiza entidades simples y bien definidas que se pueden utilizar de varias maneras.

Este diseño también me permite delegar detalles de implementación a otros desarrolladores. De esta manera, están llenando los espacios en blanco en lugar de crear un diseño de sistema completo.

La falta de un diseño general crea inconsistencias en el sistema. La crítica de iteraciones básicas y construcciones en bucle hace poco para mejorar el diseño del sistema. Este tipo de problemas se resuelve mejor con un enfoque de manos libres, StyleCop.

¿Puedes dibujar un diagrama relativamente simple del diseño general de tu sistema? Un diseño que describe los elementos / entidades involucrados en un desarrollador de un nuevo equipo. Si no puede, o está muy involucrado, entonces falta el diseño.

P.Brian.Mackey
fuente
3

En mi humilde opinión depende ...

Sus dos primeros ejemplos no son solo una cuestión de gusto personal para mí.

if (condition)
   // Do this one-line code
else
   // Do this one-line code

(sin corchetes) = más propenso a errores, si se agrega más código más adelante:

if (condition)
   // Do this one-line code
else
   // Do this one-line code
   // ...and this line as well... oops! this will actually execute either way

Y esto es menos conveniente para depurar:

new HelperClass().DoSomething(GetSomeData()); // etc.

No puede simplemente establecer un punto de interrupción donde lo necesite. Si esto es excepcional, lo suficientemente justo, pero lo discutimos como una cuestión de estilo, y una vez que tenga cosas como esta por todas partes, la depuración se vuelve más desagradable de lo que debe ser.

En cuanto a su tercer ejemplo (para vs foreach), lo veo como una cuestión de gustos.

Konrad Morawski
fuente
2

Ninguno. Evitaría reglas de codificación severas para evitar ser tedioso, quisquilloso, micro directivo y, lo peor de todo, perder el tiempo. Su sentido de autonomía es su propio problema. Si quiero que te sientas mejor contigo mismo, te compraré una ronda de tu bebida favorita. Aparte de eso, haz algo.

JeffO
fuente
2

El uso de convenciones, nombres de variables, nombres de clase, etc. es una buena práctica. Pero los estilos de codificación como los ejemplos que proporciona son bastante triviales y no tienen efecto ni en la legibilidad ni en la eficiencia del código. Por otro lado, la sobrecarga de aplicar un estilo determinado combinado con el esfuerzo de los desarrolladores para seguirlo causará problemas.

AJC
fuente
2

Utilice una herramienta de linting estándar de la industria (aparentemente FxCop para C #). Si bien no es el final, la consistencia es importante en proyectos grandes que tienen una cantidad de personas trabajando en ellos.

Si solo está trabajando en su propio proyecto o equipo pequeño, muchos argumentarán que es excesivo. Creo lo contrario (uso PEP8 para Python, incluso en mis proyectos personales de desarrollador único).

Sin embargo, la mayoría de los ejemplos que proporcionó probablemente no serían atrapados por una herramienta de linting, ya que simplemente no importan.

Demian Brecht
fuente
1

Hacer cumplir un estilo de codificación uniforme siempre es difícil. Idealmente, tal tarea mundana debería dejarse a una herramienta para manejar. Aplaudo a la comunidad lingüística de Go por hacerlo.

grokus
fuente
1

Es una mezcla de ambos. El hecho de que sea un estándar no lo hace legible y mantenible. Si todavía no hay un estándar inculcado, o si hay aspectos defectuosos e ilegibles, la revisión es apropiada.


fuente
1

En el análisis final, es el programador el que impulsa la programación. Existen problemas de estilo, pero son secundarios para sacar el programa.

Es útil dar a los programadores ALGUNAS orientaciones de estilo. Esto puede / debe hacerse antes de que los programadores se pongan a trabajar, especialmente si son principiantes relativos al medio ambiente o a la programación misma. Con orientación, algunos programadores estarán muy conscientes del estilo, otros no tanto. La orientación dada al comienzo del proyecto ayudará al primer grupo de programadores, facilitando así la tarea general. Podría hacer poco para el segundo grupo, que (con suerte) compensará en creatividad, lo que les falta de conformidad.

Tom Au
fuente
1

Creo que se reduce al tamaño del proyecto y a cuántas personas están trabajando en él. Un programador experto puede ver los dos estilos de formato diferentes y saber lo que estaba sucediendo en ambos, pero es necesario que haya una consistencia para que el ojo pueda verlo fácilmente. Si va a hacer sus declaraciones de una sola línea sin las llaves, entonces ese proyecto no debería usarlas. Quien alguna vez lidere ese proyecto debería tener esa opción. Me gusta que las cosas se vean claras y también muy compactas, ya que puedo conseguirlas. Si vas a hacer una sola línea si las estadísticas se ven mejor así

if() {}
else() {}

O incluso:

if() {} else () {}

Pero una sola línea si no debe usar el espacio de una mulitilina si. Así es como hago las cosas. No me importa cómo se llama al objeto y eso depende de cuántas veces se llame. si se llama varias veces, prefiero iniciar el objeto y depende si tiene constructores y qué no. Porque si tienes un constructor y llamas:

Object.method();
Object.method2();

Luego terminó llamando al método del constructor de objetos dos veces cuando podría haberse evitado instantaneando el objeto por completo.

Cuando se trata de foreach y para bucles También se trata del lanauge, algunos lanauges le brindan un mejor control al mirar la matriz en un bucle foreach para que tenga la clave y el valor en las matrices temporales. Y sé que algunos lanagues tienen algún tipo de optimización porque pueden mirar el bucle y saber exactamente cuántas veces se llamará.

WojonsTech
fuente
1

Si bien su primer ejemplo no es excelente (el argumento de que es más propenso a errores bajo modificaciones tiene cierto peso), en general, he crecido para preferir que los desarrolladores usen estilos de codificación ligeramente diferentes.

Después de trabajar con el código de otros miembros del equipo, a veces por tan solo unos pocos meses, esencialmente comienza a funcionar en línea git blame. Después de haber estado en mi empresa durante más de 10 años, probablemente pueda decirle con más del 80% de precisión quién escribió cualquier clase en cualquier parte de nuestras 500 mil líneas de código, solo con mirarla.

Si bien hay un poco de "tiempo de rampa" cuando comienzas a buscar código que usa un estilo con el que no estás de acuerdo, lo que realmente estás haciendo en ese momento es decir "oh, esto se parece al código de John Doe (porque usa el estilo X pero no el estilo Y, etc.) ". Y eso trae consigo un montón de contexto. Para una primera aproximación, usted sabe qué esperar del código de John: qué otras partes de la base de código entiende bien y qué partes no comprende, ya sea un gurú de SQL o un novato de GUI, etc., etc.

Ejecutar el código de todos a través de un formateador esencialmente elimina esta información, ocultándola detrás de un git blame , que no puede molestarse en ejecutar.

Matt McHenry
fuente
0

Esto realmente depende mucho del tipo de organización.

Si eres un pequeño grupo de superhéroes, cualquier tipo de estilo está bien. Si todos tienen su propio estilo, y son buenos y consistentes internamente, entonces ese es todo el proceso que necesita. Los superhéroes dirán: "Jane tiene corchetes, así que esto es lo que quiere decir" o "Jack usa camelCase para las variables".

Los estándares universales tienden a ser los mejores para convertir a todos en jugadores de B +. Tus superhéroes serán derribados por esto. Pero si quieres un jugador A y media docena de jugadores B y media docena de jugadores C para promediar hasta el B +, entonces quieres estándares consistentes. En este caso, desea que todos hagan las mismas cosas para que el jugador A pueda recorrer el código de todos lo más rápido posible.

Muchos de ustedes dicen: "Pero espera, ¿por qué no eliminar a los jugadores B y C?"

La realidad es que no hay muchos superhéroes. Si bien puede ser útil encontrarlos y nutrirlos en Google, instalar un nuevo sistema de facturación para Ma Bell puede ser más rentable con este último equipo. (Y si realmente tienes superhéroes, 4 o 5 serán dos veces más caros que una docena de juniors)

MathAttack
fuente