studio programacion móviles mpu6050 libro desarrollo curso codigo aplicaciones variables refactoring coding-style

programacion - ¿Es una buena práctica crear variables una vez usadas?



mpu6050 arduino codigo (14)

Un colega mío refactorizó este código:

private void btnGeneral_Click(object sender, RoutedEventArgs e) { Button button = (Button)e.OriginalSource; Type type = this.GetType(); Assembly assembly = type.Assembly; string userControlFullName = String.Format("{0}.{1}", type.Namespace, button.Name); UserControl userControl = (UserControl)assembly.CreateInstance(userControlFullName); }

a este código:

private void btnGeneral_Click(object sender, RoutedEventArgs e) { Button button = (Button)e.OriginalSource; Type type = this.GetType(); Assembly assembly = type.Assembly; UserControl userControl = (UserControl)assembly.CreateInstance(String.Format("{0}.{1}", type.Namespace, button.Name)); }

diciendo que no necesita crear una variable si solo se usará una vez.

Mi respuesta fue que hacer variables una vez usadas es una buena práctica ya que:

  • funciona como y reduce los comentarios (está claro lo que es "userControlFullName")
  • hace que el código sea más fácil de leer, es decir, más de su código "se lee como en inglés"
  • evita declaraciones súper largas reemplazando partes de ellas con nombres claros de variables
  • más sencillo de depurar, ya que puede pasar el mouse sobre el nombre de la variable, y en el caso de, por ejemplo, la programación de PHP sin depuradores, es más fácil hacer eco de estos nombres de variables para obtener sus valores

Los argumentos en contra de esta forma "más líneas de código", "variables innecesarias" son argumentos para facilitar la vida del compilador pero sin una velocidad significativa o ahorros de recursos.

¿Alguien puede pensar en situaciones en las que uno no debería crear nombres de variables una vez utilizados?


Ambos códigos son exactamente iguales. Por supuesto, el suyo es más legible, mantenible y depurable, pero, si ese fuera el punto de su colega, su código NO es menos consumidor de memoria.


Así es como solía codificar. Hoy en día traté de minimizar las variables intermedias. El uso de variables intermedias está perfectamente bien si es inmutable.


Como los lenguajes de programación que uso en general no me dicen qué fue nulo en una pila de excepción, generalmente intento usar variables para que no haya más de un elemento por línea. De hecho, considero que este es el limitador más significativo de la cantidad de declaraciones que quiero poner en una sola línea.

Si obtiene una excepción nula en esta afirmación de sus registros de producción, realmente está en problemas:

getCustomer (). getOrders (). iterator (). next (). getItems (). iterator (). next (). getProduct (). getName ()

Aunque estoy de acuerdo con sus ideas, agregar una variable adicional puede introducir un concepto adicional en el método y este concepto puede no ser siempre relevante para el objetivo general del método. Por lo tanto, la adición excesiva de variables también puede aumentar la complejidad del método y reducir la legibilidad. Tenga en cuenta el uso excesivo aquí.


Convenido

"hace que el código sea más fácil de leer, es decir, más de su código" se lee como en inglés "

Creo que este es el factor más importante ya que no hay diferencia en el rendimiento o la funcionalidad en la mayoría de los lenguajes moderados gestionados

Después de todo, todos sabemos que el código es más difícil de leer que escribir.

Karl


Crear una nueva variable significa un concepto más para que el lector pueda seguirlo. (Considere el caso extremo: int b = a; c = b;) Si un método es tan complejo -en tal necesidad de ruptura- que el concepto adicional es un precio que vale la pena pagar, entonces debe irse por completo y dividirse en dos métodos. De esta forma obtienes tanto el nombre significativo como el tamaño más pequeño. (Más pequeño para su método original: si es como usted dice, entonces las personas normalmente no necesitarán leer el método auxiliar).

Esa es una generalización, particularmente en un lenguaje con muchos estándares para agregar nuevos métodos, pero no va a estar en desacuerdo con la generalización con la frecuencia suficiente para que valga la pena dejar de lado su guía de estilo.


Creo que es una decisión basada en cuán ordenado quieres que sea tu código. También creo que tanto usted como su colega están en lo cierto.

En este caso, me pondría del lado de usted, colega, basado en el código que presentó (por razones de rendimiento), sin embargo, como dije antes, depende del contexto en el que se utilizará y creo que su posición es perfectamente aceptable.

Quiero señalar que la creación de variables para los parámetros usados ​​una vez puede ser inútil, a menos que sean variables const o cosas que necesite usar en muchos lugares.

Yo diría que declarar una variable utilizada una vez podría crear más confusión cuando se está depurando si hay muchas y muchas de estas, pero una aquí y otra es probable que esté bien.


Estoy completamente con su colega en principio, pero no en este caso.

El problema con las variables desechables es que introducen estado, y más estado significa que el código es más difícil de entender ya que no se conocen los efectos que podría tener en el flujo del programa. La programación funcional no tiene variables en absoluto, exactamente por esta razón. De modo que cuantas menos variables haya, mejor. La eliminación de variables es buena.

Sin embargo, en este caso particular, donde el método termina justo después del único uso de la variable, las desventajas de tenerlo son mínimas, y las ventajas que menciona son probablemente más sustanciales.


Estoy completamente contigo en este.

Especialmente uso esto si un método toma muchos booleanos, es decir,

public void OpenDocument(string filename, bool asReadonly, bool copyLocal, bool somethingElse)

Para mí esto es mucho más legible:

bool asReadonly = true; bool copyLocal = false; bool somethingElse = true; OpenDocument("somefile.txt", asReadonly, copyLocal, somethingElse);

..que:

OpenDocument("somefile.txt", true, false, true);


Estoy con tu opinión en este caso. La legibilidad es la clave. Estoy seguro de que el compilador produce el mismo ejecutable en ambos casos, con los compiladores tan inteligentes como lo son hoy.

Pero yo no diría que "siempre use variables una vez usadas" tampoco. Ejemplo:

String name = "John"; person.setName(name);

es innecesario, porque

person.setName("John");

lee igualmente bien, si no incluso mejor. Pero, por supuesto, no todos los casos son tan claros. "Legibilidad" es un término subjetivo, después de todo.


Estoy de acuerdo con la mayoría aquí, la legibilidad del código es clave.

Es un cruzado de recuento de línea poco frecuente que realmente escribe código altamente legible y altamente mantenible.

Además, todo se compila en MSIL de todos modos y el compilador optimizará mucho para usted.

En el siguiente ejemplo, el compilador optimizará el código de todos modos:

List<string> someStrings = new List<string>(); for (int i = 0; i < 1000; i++) { string localString = string.Format("prefix{0}", i); someStrings.Add(localString); }

Más bien que:

List<string> someStrings = new List<string>(); string localString = string.Empty; for (int i = 0; i < 1000; i++) { localString = string.Format("prefix{0}", i); someStrings.Add(localString); }

Por lo tanto, en realidad no existe un motivo de rendimiento para no ir en muchos casos.


Intentando crear un argumento en contra de introducir nuevas variables, diría que cuando lees el código (por primera vez, al menos), no sabes si la variable se está utilizando más de una vez. Así que de inmediato dejará que sus ojos escaneen el código para ver si se usa en más lugares. Cuanto más larga sea la función, más tendrá que mirar para ver si puede encontrarla.

¡Ese es el mejor argumento contra el que puedo pensar! :-)


Supongo que en algunos casos podría tener un efecto en el rendimiento. En particular en este ejemplo:

for (int i1 = 0; i1 < BIG_NR; i1++) { for (int i2 = 0; i2 < BIG_NR; i2++) { for (int i3 = 0; i3 < BIG_NR; i3++) { for (int i4 = 0; i4 < BIG_NR; i4++) { int amount = a + b; someVar[i1][i2][i3][i4] = amount; } } } }

... la asignación adicional podría tener un impacto demasiado grande en el rendimiento. Pero, en general, tus argumentos son 100% correctos.


Todas tus razones me parecen válidas.

Hay ocasiones en las que efectivamente debe evitar el uso de variables intermedias, donde necesita una única expresión (por ejemplo, para la inicialización de variables miembro en Java / C #) pero introducir una variable adicional para mayor claridad está absolutamente bien donde sea aplicable. Obviamente no lo hagas para cada argumento de cada método, pero con moderación puede ayudar mucho.

El argumento de depuración es particularmente sólido: también es muy agradable poder pasar las líneas que "preparan" los argumentos a un método, y pasar directamente al método en sí, habiendo visto los argumentos fácilmente en el depurador.


Tu colega no parece ser consistente.

La solución consistente se ve así:

private void btnGeneral_Click(object sender, RoutedEventArgs e) { UserControl userControl = ((UserControl)type.Assembly).CreateInstance(String.Format("{0}.{1}", this.GetType().Namespace, ((Button)e.OriginalSource).Name)); }