2010-05-18 14 views
7

Si tengo un método que hace múltiples cosas relacionadas, ¿es una buena práctica pegar cada "cosa" que hace el método en un bloque separado?¿Es una buena práctica separar el código en bloques?

Ej.

{ 
int var 
//Code 
} 

{ 
int var 
//More Code 
} 

Sería de gran ayuda a reducir el número de variables locales, y hacer que el código sea más legible, pero no estoy seguro de si es una buena idea.

Respuesta

0

Bueno, ciertamente es una buena práctica restringir el alcance de las variables tanto como sea posible. Son menos propensos a ser reutilizados innecesariamente, y es más probable que los defina cuando los declara, lo que evita errores debido a variables indefinidas y cosas por el estilo. También hay muchos casos en los que tienes un objeto que hace algo mientras está construido y cuando se destruye, y quieres abarcarlo (por ejemplo, el reloj de arena en MFC se muestra mientras su objeto existe y desaparece cuando se destruye en MFC ; los objetos para bloquear y desbloquear mutex son otro buen ejemplo), y en tales casos, el alcance de las variables con llaves tiene sentido. Por lo tanto, hay muchos casos en los que tiene sentido crear bloques de código específicamente para variables de ámbito.

Sin embargo, hay algunos problemas para hacer esto en exceso.

  1. Puede ser difícil de leer si tiene muchos bloques de código dentro de una función.

  2. Si intenta demasiado a fondo las variables lo más posible, se encontrará con problemas al declarar variables que necesitan un alcance mayor antes de lo que lo haría y no siempre puede definirlas al declararlas.

  3. Las funciones a menudo expresan lo que intenta hacer mucho mejor.

Por lo tanto, el uso de llaves adicionales para variables de ámbito puede ser una buena práctica (reduciendo el ámbito de las variables tanto como sea razonablemente posible, sin duda lo es), pero en muchos casos, es mucho mejor para romper el código en múltiples funciones . El código puede ser mucho más fácil de entender cuando tienes funciones con nombre que bloques arbitrarios de código. Entonces, si está en una posición en la que desea declarar muchos bloques de código separados dentro de una función, considere dividirlo en varias funciones; esto es especialmente cierto si cada uno de esos bloques está directamente dentro de la función en lugar de anidado más. Por lo tanto, los casos de

T func(...) 
{ 
    { 
     ... 
    } 

    { 
     ... 
    } 
} 

probablemente se dividan mejor en funciones múltiples que bloques separados.

Ciertamente hay momentos en que los bloques separados pueden ser buenos y útiles, pero generalmente las funciones separadas serían mejores.

15

Si su función hace varias cosas que son lo suficientemente largas como para considerar dividir esas cosas en bloques como este, entonces probablemente debería dividir la función en varias funciones más pequeñas.

Existen, por supuesto, escenarios en los que es útil introducir un nuevo bloque de alcance. Por ejemplo, si usa un scoped_lock de algún tipo para bloquear un mutex u otro objeto de sincronización, puede asegurarse de que solo mantenga presionado el bloqueo durante el tiempo mínimo necesario introduciendo un bloque de alcance.

3

Lo primero que haría al enfrentar esto es considerar la refactorización para dividir la función en funciones más pequeñas y cohesivas.

Al final, todo se reduce a la legibilidad, si el alcance lo hace más legible, entonces es probable que sea una buena idea. Si, por otro lado, va a confundir a las personas que miran tu código, probablemente deberías evitarlo.

3

Si tiene un método que hace múltiples cosas relacionadas, diría que está rompiendo el Principio de Responsabilidad Individual. SRP se refiere a los objetos, pero me gusta aplicar el mismo pensamiento a los métodos y funciones por igual. Sería una buena práctica pegar cada "cosa" que hace el método en métodos separados (probablemente privados o protegidos) y ajustarlos en su método actual. Consulte la refactorización Extract Method.

¡Cualquier cosa que pueda hacer para que su código sea más legible es una buena idea! Las funciones más pequeñas que hacen una cosa son más legibles que las funciones largas que hacen muchas cosas. También son más reutilizables.

4

Los patrones de implementación de Kent Beck tienen un capítulo muy bueno sobre este tema. Dividir en bloques ayudará a refactorizar en funciones separadas.

Por ejemplo se convertirá en

void process() { 
    input(); 
    tally(); 
    output(); 
} 
algo como esto

void process() { 
//code for input 
//code for increments /tally 
//code to populate objects and output 
} 

Cuestiones relacionadas