¿En qué punto la brevedad ya no es una virtud?


102

Una corrección de error reciente me obligó a revisar el código escrito por otros miembros del equipo, donde encontré esto (es C #):

return (decimal)CostIn > 0 && CostOut > 0 ? (((decimal)CostOut - (decimal)CostIn) / (decimal)CostOut) * 100 : 0;

Ahora, permitiendo que haya una buena razón para todos esos lanzamientos, esto todavía parece muy difícil de seguir. Hubo un pequeño error en el cálculo y tuve que desenredarlo para solucionar el problema.

Conozco el estilo de codificación de esta persona de la revisión de código, y su enfoque es que más corto es casi siempre mejor. Y, por supuesto, hay valor allí: todos hemos visto cadenas innecesariamente complejas de lógica condicional que podrían arreglarse con unos pocos operadores bien ubicados. Pero es claramente más experto que yo en seguir cadenas de operadores concentrados en una sola declaración.

Esto es, por supuesto, en última instancia, una cuestión de estilo. Pero, ¿se ha escrito o investigado algo sobre el reconocimiento del punto en el que luchar por la brevedad del código deja de ser útil y se convierte en una barrera para la comprensión?

El motivo de los casts es Entity Framework. El db necesita almacenar estos como tipos anulables. ¿Decimal? no es equivalente a Decimal en C # y necesita ser lanzado.


153
Cuando la brevedad triunfa sobre la legibilidad.
Robert Harvey

27
Mirando su ejemplo específico: un reparto es (1) un lugar donde el desarrollador sabe más que el compilador y necesita decirle al compilador un hecho que no puede deducirse, o (2) donde se almacenan algunos datos en el "error" "escriba los tipos de operaciones que debemos realizar en él. Ambos son fuertes indicadores de que algo podría ser refactorizado. La mejor solución aquí es encontrar una manera de escribir el código sin conversiones.
Eric Lippert el

29
En particular, parece extraño que sea necesario convertir CostIn en decimal para compararlo con cero, pero no CostOut; ¿porqué es eso? ¿Cuál es el tipo de costo en la tierra que solo se puede comparar con cero al convertirlo en decimal? ¿Y por qué CostOut no es del mismo tipo que CostIn?
Eric Lippert el

12
Además, la lógica aquí en realidad puede estar equivocada. Supongamos que CostOutes igual a Double.Epsilon, y por lo tanto es mayor que cero. Pero (decimal)CostOutes en ese caso cero, y tenemos una división por cero error. El primer paso debería ser obtener el código correcto , lo cual creo que no lo es. Hazlo correctamente, crea casos de prueba y luego hazlo elegante . El código elegante y el código breve tienen mucho en común, pero a veces la brevedad no es el alma de la elegancia.
Eric Lippert el

55
La brevedad es siempre una virtud. Pero nuestra función objetivo combina la brevedad con otras virtudes. Si uno puede ser más breve sin dañar otras virtudes, siempre debería hacerlo.
Solomonoff's Secret

Respuestas:


163

Para responder a su pregunta sobre la investigación existente

Pero, ¿se ha escrito o investigado algo sobre el reconocimiento del punto en el que luchar por la brevedad del código deja de ser útil y se convierte en una barrera para la comprensión?

Sí, ha habido trabajo en esta área.

Para comprender estas cosas, debe encontrar una manera de calcular una métrica para que las comparaciones se puedan realizar de forma cuantitativa (en lugar de simplemente realizar la comparación basada en el ingenio y la intuición, como hacen las otras respuestas). Una posible métrica que se ha examinado es

Complejidad ciclomática ÷ Líneas de código fuente ( SLOC )

En su ejemplo de código, esta relación es muy alta, porque todo se ha comprimido en una línea.

El SATC ha encontrado que la evaluación más efectiva es una combinación de tamaño y complejidad [ciclomática]. Los módulos con una alta complejidad y un gran tamaño tienden a tener la fiabilidad más baja. Los módulos con bajo tamaño y alta complejidad también son un riesgo de confiabilidad porque tienden a ser códigos muy concisos, lo cual es difícil de cambiar o modificar.

Enlazar

Aquí hay algunas referencias si está interesado:

McCabe, T. y A. Watson (1994), Complejidad de software (CrossTalk: The Journal of Defense Software Engineering).

Watson, AH y McCabe, TJ (1996). Pruebas estructuradas: una metodología de prueba que utiliza la métrica de complejidad ciclomática (publicación especial NIST 500-235). Recuperado el 14 de mayo de 2011 del sitio web de McCabe Software: http://www.mccabe.com/pdf/mccabe-nist235r.pdf

Rosenberg, L., Hammer, T., Shaw, J. (1998). Software Metrics and Reliability (Actas del Simposio Internacional IEEE sobre Ingeniería de Confiabilidad de Software). Recuperado el 14 de mayo de 2011 del sitio web de la Universidad Penn State: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.104.4041&rep=rep1&type=pdf

Mi opinion y solucion

Personalmente, nunca he valorado la brevedad, solo la legibilidad. A veces, la brevedad ayuda a la lectura, a veces no. Lo que es más importante es que está escribiendo Código realmente obvio (ROC) en lugar de Código de solo escritura (WOC).

Solo por diversión, así es como lo escribiría, y pedirle a los miembros de mi equipo que lo escriban:

if ((costIn <= 0) || (costOut <= 0)) return 0;
decimal changeAmount = costOut - costIn;
decimal changePercent = changeAmount / costOut * 100;
return changePercent;

Tenga en cuenta también que la introducción de las variables de trabajo tiene el efecto secundario de activar la aritmética de punto fijo en lugar de la aritmética de enteros, por lo que decimalse elimina la necesidad de todos esos lanzamientos .


44
Realmente me gusta la cláusula de guardia para el caso de menos de cero. Podría merecer un comentario: ¿cómo puede un costo ser menor que cero? ¿Qué caso especial es ese?
user949300

22
+1. Probablemente agregaría algo comoif ((costIn < 0) || (costOut < 0)) throw new Exception("costs must not be negative");
Doc Brown

13
@DocBrown: Esa es una buena sugerencia, pero consideraría si la ruta de código excepcional puede ejercerse mediante una prueba. En caso afirmativo, escriba un caso de prueba que ejercite esa ruta de código. Si no, entonces cambie todo a una Afirmación.
Eric Lippert el

12
Si bien todos estos son buenos puntos, creo que el alcance de esta pregunta es, estilo de código, no lógica. Mi recorte de código es un esfuerzo de equivalencia funcional desde una perspectiva de caja negra. Lanzar una excepción no es lo mismo que devolver 0, por lo que esa solución no sería funcionalmente equivalente.
John Wu

30
"Personalmente, nunca he valorado la brevedad, solo la legibilidad. A veces la brevedad ayuda a la legibilidad, a veces no". Excelente punto +1 solo por eso. También me gusta tu solución de código.
Comodín el

49

La brevedad es buena cuando reduce el desorden en torno a las cosas importantes, pero cuando se vuelve breve , al empaquetar demasiados datos relevantes con demasiada densidad para poder seguirlos fácilmente, los datos relevantes se vuelven desordenados y usted tiene un problema.

En este caso particular, los lanzamientos a decimalse repiten una y otra vez; probablemente sería mejor en general reescribirlo como algo así:

var decIn = (decimal)CostIn;
var decOut = (decimal)CostOut;
return decIn > 0 && CostOut > 0 ? (decOut - decIn ) / decOut * 100 : 0;
//                  ^ as in the question

De repente, la línea que contiene la lógica es mucho más corta y cabe en una línea horizontal, por lo que puede ver todo sin tener que desplazarse, y el significado es mucho más evidente.


1
Probablemente habría ido más lejos y refactorizado ((decOut - decIn ) / decOut) * 100a otra variable.
FrustratedWithFormsDesigner

99
Assembler fue mucho más claro: solo una operación por línea. Doh!

2
@FrustratedWithFormsDesigner Incluso iría un paso más allá y envolvería la verificación condicional entre paréntesis.
Chris Cirefice

1
@FrustratedWithFormsDesigner: extraer esto antes del condicional evitaría la comprobación de división por cero ( CostOut > 0), por lo que tendría que expandir el condicional en una ifdeclaración. No es que haya nada de malo en esto, pero agrega más verbosidad que solo la introducción de un local.
wchargin

1
Para ser honesto, simplemente deshacerse de los moldes parece que emitió suficiente IMO, si a alguien le resulta difícil de leer porque no puede reconocer un cálculo de tasa básica simple, ese es su problema, no el mío.
Walfrat

7

Si bien no puedo citar ninguna investigación en particular sobre el tema, sugeriría que todos esos lanzamientos dentro de su código violen el principio de No repetirse. Lo que parece que intenta hacer su código es convertir costIny costOutescribir Decimal, y luego realizar algunas comprobaciones de los resultados de dichas conversiones, y realizar operaciones adicionales en esos valores convertidos si pasan las comprobaciones. De hecho, su código realiza una de las comprobaciones de cordura en un valor no convertido, lo que aumenta la posibilidad de que costOut pueda tener un valor mayor que cero, pero menor que la mitad del tamaño que el menor que no sea cero que Decimalpuede representar. El código sería mucho más claro si definiera variables de tipo Decimalpara contener los valores convertidos, y luego actuara sobre ellos.

Parece curioso que le interese más la razón de las Decimalrepresentaciones de costIny costOutque la razón de los valores reales de costIny costOut, a menos que el código también use las representaciones decimales para algún otro propósito. Si el código va a hacer un mayor uso de esas representaciones, ese sería un argumento adicional para crear variables para contener esas representaciones, en lugar de tener una secuencia continua de conversiones en todo el código.


Los moldes (decimales) probablemente satisfagan algunos requisitos de las reglas de negocio. Al tratar con contadores, a veces tienes que saltar a través de estúpidos aros. Pensé que el CFO iba a tener un ataque al corazón cuando encontró la línea "Usar corrección de redondeo de impuestos - $ 0.01" que era inevitable dada la funcionalidad solicitada. (Suministrado: precio después de impuestos. Tengo que calcular el precio antes de impuestos. Las probabilidades de que no haya respuesta es igual a la tasa impositiva).
Loren Pechtel

@LorenPechtel: Dado que la precisión con la que Decimalse redondeará un yeso depende de la magnitud del valor en cuestión, me resulta difícil imaginar reglas de negocio que exigirían la forma en que se comportarán realmente los yesos.
supercat

1
Buen punto: me había olvidado de los detalles del tipo decimal porque nunca he tenido la oportunidad de querer algo así. Ahora creo que esto es obediencia al culto de la carga a las reglas comerciales, específicamente, el dinero no debe ser un punto flotante.
Loren Pechtel

1
@LorenPechtel: Para aclarar mi último punto: un tipo de punto fijo puede garantizar que x + yy se desborde o produzca y. El Decimaltipo no lo hace. El valor 1.0d / 3.0 tendrá más dígitos a la derecha del decimal que los que se pueden mantener cuando se usan números más grandes. Por lo tanto, sumar y restar el mismo número mayor provocará una pérdida de precisión. Los tipos de punto fijo pueden perder precisión con la multiplicación o división fraccionaria, pero no con la suma, resta, multiplicación o división con resto (por ejemplo, 1.00 / 7 es 0.14 resto 0.2; 1.00 div 0.15 es 6 resto 0.10).
supercat

1
@ Hulk: Sí, por supuesto. Estaba debatiendo si usar x + yy produciendo x, x + yx produciendo y, o x + yxy, y terminé confundiendo los dos primeros. Lo importante es que los tipos de punto fijo pueden garantizar que muchas secuencias de operaciones nunca causarán errores de redondeo no detectados de ninguna magnitud. Si el código agrega cosas juntas de diferentes maneras para verificar que los totales coincidan (por ejemplo, comparando la suma de los subtotales de fila con la suma de los subtotales de columna), tener resultados que sean exactamente iguales es mucho mejor que hacer que salgan "cerca".
supercat

5

Miro ese código y pregunto "¿cómo puede un costo ser 0 (o menos)?". ¿Qué caso especial indica eso? El código debe ser

bool BothCostsAreValidProducts = (CostIn > 0) && (CostOut > 0);
if (!BothCostsAreValidProducts)
  return NO_PROFIT;
else {
   // that calculation here...
}

Estoy adivinando los nombres aquí: cambio BothCostsAreValidProductsy NO_PROFITsegún corresponda.


Por supuesto, los costos pueden ser cero (piense en los regalos de Navidad). Y en tiempos de tasas de interés negativas, los costos negativos tampoco deberían ser demasiado sorprendentes y al menos el código debería estar preparado para lidiar con eso (y sea arrojando errores)
Hagen von Eitzen

Estás en el camino correcto.
danny117

Eso es tonto. if (CostIn <= 0 || CostOut <= 0)Está completamente bien.
Miles Rout

Mucho menos legible. El nombre de la variable es horrible (BothCostsAreValid sería mejor. Aquí no hay nada acerca de los productos). Pero incluso eso no agrega nada a la legibilidad, porque solo al verificar CostIn, CostOut está bien. Introduciría una variable adicional con un nombre significativo si el significado de la expresión que se está probando no es obvio.
gnasher729

5

La brevedad deja de ser una virtud cuando olvidamos que es un medio para un fin en lugar de una virtud en sí misma. Nos gusta la brevedad porque se correlaciona con la simplicidad, y nos gusta la simplicidad porque el código más simple es más fácil de entender y más fácil de modificar y contiene menos errores. Al final, queremos que el código logre este objetivo:

  1. Cumplir los requisitos comerciales con la menor cantidad de trabajo.

  2. Evitar errores

  3. Permítanos hacer cambios en el futuro que continúen cumpliendo 1 y 2

Estas son las metas. Cualquier principio o método de diseño (ya sea KISS, YAGNI, TDD, SOLID, pruebas, sistemas de tipos, metaprogramación dinámica, etc.) son solo virtuosos en la medida en que nos ayudan a lograr estos objetivos.

La línea en cuestión parece haber perdido de vista el objetivo final. Si bien es breve, no es simple. En realidad, contiene redundancia innecesaria al repetir la misma operación de conversión varias veces. La repetición de código aumenta la complejidad y la probabilidad de errores. Entremezclar el casting con el cálculo real también hace que el código sea difícil de seguir.

La línea tiene tres preocupaciones: Guardias (carcasa especial 0), tipo de fundición y cálculo. Cada preocupación es bastante simple cuando se toma de forma aislada, pero debido a que todo se ha mezclado en la misma expresión, se hace difícil de seguir.

No está claro por qué CostOutno se lanza la primera vez que se usa CostIn. Puede haber una buena razón, pero la intención no es clara (al menos no sin contexto), lo que significa que un mantenedor sería cauteloso de cambiar este código porque podría haber algunas suposiciones ocultas. Y esto es anatema para la mantenibilidad.

Como CostInse lanza antes de comparar con 0, supongo que es un valor de coma flotante. (Si fuera un int no habría razón para lanzar). Pero si CostOutes un flotante, entonces el código podría ocultar un oscuro error de dividir por cero, ya que un valor de coma flotante puede ser pequeño pero no cero, pero cero cuando se convierte a un decimal (al menos creo que esto sería posible).

Entonces, el problema no es la brevedad o la falta de ella, el problema es la lógica repetida y la combinación de preocupaciones que conducen a un código difícil de mantener.

La introducción de variables para mantener los valores emitidos probablemente aumentaría el tamaño del código contado en cantidad de tokens, pero disminuirá la complejidad, separará las preocupaciones y mejorará la claridad, lo que nos acerca al objetivo del código que es más fácil de entender y mantener.


1
Un punto importante: Casting CostIn una vez en vez de dos lo hace ilegible, porque el lector no tiene idea de si se trata de un error sutil con una solución obvia, o si esto se hace intencionalmente. Claramente, si no puedo decir con certeza qué quiso decir el escritor con una oración, entonces no es legible. Debería haber dos lanzamientos o un comentario que explique por qué el primer uso de CostIn no requiere o no debería tener un lanzamiento.
gnasher729

3

La brevedad no es una virtud en absoluto. La legibilidad es LA virtud.

La brevedad puede ser una herramienta para lograr la virtud o, como en su ejemplo, puede ser una herramienta para lograr algo exactamente opuesto. De esta forma u otra, casi no tiene valor propio. La regla de que el código debe ser "lo más breve posible" también se puede reemplazar por "lo más obsceno posible": todos son igualmente sin sentido y potencialmente perjudiciales si no sirven para un propósito mayor.

Además, el código que ha publicado ni siquiera sigue la regla de brevedad. Habían las constantes pueden declarar con sufijo M, la mayor parte de los horribles (decimal)moldes podrían evitarse, ya que el compilador promovería restante inta decimal. Creo que la persona que estás describiendo simplemente usa la brevedad como excusa. Lo más probable es que no deliberadamente, pero aún así.


2

En mis años de experiencia, he llegado a creer que la brevedad final es la del tiempo : el tiempo domina todo lo demás. Eso incluye tanto el tiempo de rendimiento, el tiempo que tarda un programa en hacer un trabajo, y el tiempo de mantenimiento, el tiempo que lleva agregar funciones o corregir errores. (La forma de equilibrar esos dos depende de la frecuencia con la que se realiza el código en cuestión en lugar de mejorarlo; recuerde que la optimización prematura sigue siendo la raíz de todo mal ). La brevedad del código es para mejorar la brevedad de ambos; el código más corto generalmente se ejecuta más rápido y, por lo general, es más fácil de entender y, por lo tanto, mantener Si tampoco funciona, entonces es un negativo neto.

En el caso que se muestra aquí, creo que la brevedad del texto se ha malinterpretado como brevedad del recuento de líneas, a expensas de la legibilidad, lo que puede aumentar el tiempo de mantenimiento. (También puede llevar más tiempo realizarlo, dependiendo de cómo se realice el lanzamiento, pero a menos que la línea anterior se ejecute millones de veces, probablemente no sea una preocupación). En este caso, los lanzamientos decimales repetitivos restan legibilidad, ya que es más difícil de leer. Vea cuál es el cálculo más importante. Hubiera escrito lo siguiente:

decimal dIn = (decimal)CostIn;
decimal dOut = (decimal)CostOut;
return dIn > 0 && CostOut > 0 ? ((dOut - dIn) / dOut) * 100 : 0;

(Editar: este es el mismo código que la otra respuesta, así que ahí lo tienes).

Soy fanático del operador ternario ? :, así que lo dejaría.


55
Los ternarios son difíciles de leer, especialmente si hay expresiones más allá de un único valor o variable en los valores de retorno.
Almo

Me pregunto si eso es lo que está impulsando los votos negativos. Excepto que lo que escribí está de acuerdo con Mason Wheeler, actualmente con 10 votos. También dejó el ternario. No sé por qué tanta gente tiene un problema ? :: creo que el ejemplo anterior es lo suficientemente compacto, especialmente. en comparación con un if-then-else.
Paul Brinkley

1
Realmente no estoy seguro. No te menosprecié. No me gustan los ternarios porque no está claro qué hay a ambos lados del :. if-elsese lee como inglés: no se puede perder lo que significa.
Almo

FWIW Sospecho que estás recibiendo votos negativos porque esta es una respuesta muy similar a la de Mason Wheeler, pero la suya es la primera.
Bob Tway

1
¡Muerte al operador ternario! (también, muerte a tabuladores, ni espacios y cualquier modelo de horquillado y sangría, excepto Allman (de hecho, The Donald (tm) ha twitteado que estas serán las tres primeras leyes que
promulgó

2

Como casi todas las respuestas anteriores, la legibilidad siempre debe ser su objetivo principal. Sin embargo, también pienso que el formateo puede ser una forma más efectiva de lograr esto en lugar de crear variables y nuevas líneas.

return ((decimal)CostIn > 0 && CostOut > 0) ?
       100 * ( (decimal)CostOut - (decimal)CostIn ) / (decimal)CostOut:
       0;

Estoy totalmente de acuerdo con el argumento de la complejidad ciclomática en la mayoría de los casos, sin embargo, su función parece ser lo suficientemente pequeña y simple como para abordarla mejor con un buen caso de prueba. Por curiosidad, ¿por qué la necesidad de convertir a decimal?


44
El motivo de los casts es Entity Framework. El db necesita almacenar estos como tipos anulables. ¿Doble? no es equivalente a Double en C # y necesita ser lanzado.
Bob Tway

2
@MattThrower Quieres decir decimal, ¿verdad? double! = decimal, hay una gran diferencia.
pinkfloydx33

1
@ pinkfloydx33 sí! Escribiendo en un teléfono con solo medio cerebro ocupado :)
Bob Tway

Tengo que explicar a mis alumnos que los tipos de datos SQL son extrañamente diferentes de los tipos utilizados en los lenguajes de programación. Sin embargo, no he podido explicarles por qué . "¡No lo sé!" "¡Pequeño endian!"

3
No me parece legible en absoluto.
Almo

1

Para mí, parece que un gran problema con la legibilidad aquí radica en la falta total de formato.

Lo escribiría así:

return (decimal)CostIn > 0 && CostOut > 0 
            ? (((decimal)CostOut - (decimal)CostIn) / (decimal)CostOut) * 100 
            : 0;

Dependiendo de si el tipo de CostIny CostOutes un tipo de punto flotante o un tipo integral, algunos de los modelos también pueden ser innecesarios. A diferencia de floaty double, los valores integrales se promueven implícitamente a decimal.


Lamento ver que esto fue rechazado sin explicación, pero me parece idéntico a la respuesta de mochilacodes menos algunos de sus comentarios, así que supongo que estaba justificado.
PJTraill

@PJTraill Debo haberme perdido eso, de hecho es casi idéntico. Sin embargo, prefiero tener los operadores en las nuevas líneas, por lo que dejaré que mi versión permanezca.
Felix Dombek

Estoy de acuerdo con los operadores, como comenté en un comentario sobre la otra respuesta: no había visto que lo había hecho como prefiero.
PJTraill

0

El código se puede escribir a toda prisa, pero el código anterior debería escribirse en mi mundo con nombres de variables mucho mejores.

Y si leo el código correctamente, entonces está tratando de hacer un cálculo de margen bruto.

var totalSales = CostOut;
var totalCost = CostIn;
var profit = (decimal)(CostOut - CostIn);
var grossMargin = 0m; //profit expressed as percentage of totalSales

if(profit > 0)
{
    grossMargin = profit/totalSales*100
}

3
Perdiste la división entre cero y devuelve cero.
danny117

1
y es por eso que es difícil refactorizar el código de otra persona que es maximizado por brevedad y por qué es bueno tener comentarios adicionales para explicar por qué / cómo funcionan las cosas
Rudolf Olah

0

Supongo que CostIn * CostOut son enteros
Así es como lo escribiría
M (Money) es decimal

return CostIn > 0 && CostOut > 0 ? 100M * (CostOut - CostIn) / CostOut : 0M;

1
con la esperanza de que no sean ambos pensamientos negativos: p
Walfrat

2
¿Está el divido por cero todavía allí?
danny117

@ danny117 Cuando la brevedad arroja la respuesta incorrecta, ha llegado demasiado lejos.
paparazzo

No quiero actualizar la pregunta y activarla. Los 100M y 0M fuerzan el decimal. Creo que (CostOut - CostIn) se realizará como matemática entera y luego la diferencia se convierte en decimal.
paparazzo

0

El código está escrito para ser entendido por las personas; la brevedad en este caso no compra mucho y aumenta la carga sobre el mantenedor. Por esta brevedad, debe expandirlo ya sea haciendo que el código sea más autodocumentado (mejores nombres de variables) o agregando más comentarios que expliquen por qué funciona de esta manera.

Cuando escribe código para resolver un problema hoy, ese código podría ser un problema mañana cuando los requisitos cambien. Siempre se debe tener en cuenta el mantenimiento y es esencial mejorar la comprensión del código.


1
Aquí es donde entran en juego las prácticas y principios de Ingeniería de Software. Requisitos no funcionales
hanzolo

0

La brevedad ya no es una virtud cuando

  • Hay una división sin un cheque previo para cero.
  • No hay comprobación para nulo.
  • No hay limpieza
  • PRUEBA DE CAPTURA versus arroja la cadena alimentaria donde se puede manejar el error.
  • Se hacen suposiciones sobre el orden de finalización de las tareas asincrónicas.
  • Tareas con retraso en lugar de reprogramación en el futuro
  • Se usa IO innecesario
  • No usar actualización optimista

Cuando no hay una respuesta lo suficientemente larga.

1
Ok, esto debería haber sido un comentario, no una respuesta. Pero es un chico nuevo, así que al menos explícalo; ¡no solo rechaces y huyas! Bienvenido a bordo, Danny. Cancelé un voto negativo, pero la próxima vez haga un comentario :-)
Mawg

2
Ok, extendí la respuesta para incluir algunas cosas más complejas que aprendí de la manera difícil y fácil de escribir código breve.
danny117

Gracias por la bienvenida @Mawg. Quiero señalar que la comprobación de nulo es lo que encuentro con más problemas en el código breve.
danny117

Acabo de editar a través de Android y no solicitó una descripción de la edición.
Agregué una

0

Si esto pasaba las pruebas de la unidad de validación, entonces estaría bien, si se agregara una nueva especificación, se requiriera una nueva prueba o una implementación mejorada, y se requiriera "desenredar" la brevedad del código, es decir cuando El problema surgiría.

Obviamente, un error en el código muestra que hay otro problema con Q / A que fue un descuido, por lo que el hecho de que haya un error que no se detectó es motivo de preocupación.

Cuando se trata de requisitos no funcionales, como la "capacidad de lectura" del código, debe ser definido por el gerente de desarrollo y administrado por el desarrollador principal y respetado por los desarrolladores para garantizar implementaciones adecuadas.

Trate de garantizar una implementación estandarizada de código (estándares y convenciones) para garantizar la "legibilidad" y la facilidad de "mantenibilidad". Pero si estos atributos de calidad no se definen y aplican, entonces terminará con un código como el ejemplo anterior.

Si no le gusta ver este tipo de código, intente lograr que el equipo esté de acuerdo con los estándares y convenciones de implementación y anótelo y realice revisiones de código al azar o verificaciones puntuales para validar que se respete la convención.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.