Supongamos que tengo un método largo como este:
public void SomeLongMethod()
{
// Some task #1
...
// Some task #2
...
}
Este método no tiene partes repetitivas que se deben mover a un método separado o función local.
Hay muchas personas (incluido yo) que piensan que los métodos largos son olores de código. Además, no me gusta la idea de usar #region
aquí y hay una respuesta muy popular que explica por qué esto es malo .
Pero si separo este código en métodos
public void SomeLongMethod()
{
Task1();
Task2();
}
private void Task1()
{
// Some task #1
...
}
private void Task2()
{
// Some task #1
...
}
Veo los siguientes problemas:
Contaminar el alcance de la definición de clase con definiciones que se usan internamente por un solo método y que significa que debo documentar en algún lugar
Task1
y queTask2
están destinadas solo a elementos internos deSomeLongMethod
(o cada persona que lea mi código tendrá que inferir esta idea).Contaminación IDE autocompletar (por ejemplo, Intellisense) de métodos que se utilizarían solo una vez dentro del
SomeLongMethod
método único .
Entonces, si separo este código de método en funciones locales
public void SomeLongMethod()
{
Task1();
Task2();
void Task1()
{
// Some task #1
...
}
void Task2()
{
// Some task #1
...
}
}
entonces esto no tiene los inconvenientes de los métodos separados, pero esto no se ve mejor (al menos para mí) que el método original.
¿Qué versión de SomeLongMethod
es más fácil de mantener y legible para usted y por qué?
fuente
Respuestas:
Las tareas autónomas deben trasladarse a métodos autónomos. No hay inconveniente lo suficientemente grande como para anular este objetivo.
Usted dice que contaminan el espacio de nombres de la clase, pero esa no es la compensación que debe tener en cuenta al factorizar su código. Es mucho más probable que un futuro lector de la clase (por ejemplo, usted) pregunte "¿Qué hace este método específico y cómo debo cambiarlo para que haga lo que dicen los requisitos modificados?" que "¿Cuál es el propósito y el sentido de ser de todos los métodos en la clase? " Por lo tanto, hacer que cada uno de los métodos sea más fácil de entender (al tener menos elementos) es mucho más importante que hacer que toda la clase sea más fácil de entender (haciéndolo tener menos métodos).
Por supuesto, si las tareas no son realmente autónomas pero requieren que algunas variables de estado se muevan, entonces un objeto de método, un objeto auxiliar o una construcción similar puede ser la opción correcta. Y si las tareas son totalmente autónomas y no están vinculadas con el dominio de la aplicación (por ejemplo, solo el formato de cadena, entonces posiblemente deberían ir a una clase completamente diferente (utilidad). Pero eso no cambia el hecho de que " mantener métodos bajos por clase "es, en el mejor de los casos, un objetivo muy secundario.
fuente
No me gusta ninguno de los enfoques. No proporcionó ningún contexto más amplio, pero la mayoría de las veces se ve así:
Tiene una clase que hace algún trabajo al combinar el poder de múltiples servicios en un solo resultado.
Cada uno de sus servicios implementa solo una parte de la lógica. Algo especial, que solo este servicio puede hacer. Si tiene otros métodos privados además de los que admiten la API principal para que pueda ordenarlos fácilmente y no debería haber demasiados de todos modos.
La conclusión es: si comienza a crear regiones en su código para agrupar métodos, es hora de comenzar a pensar en encapsular su lógica con un nuevo servicio.
fuente
El problema con la creación de funciones dentro del método es que no reduce la longitud del método.
Si desea el nivel adicional de protección 'privado al método', puede crear una nueva clase
Pero las clases en las clases son muy feas: /
fuente
Minimizar el alcance de las construcciones del lenguaje como variables y métodos es una buena práctica. Por ejemplo, evite las variables globales. Hace que el código sea más fácil de entender y ayuda a evitar el mal uso porque se puede acceder a la construcción en menos lugares.
Esto habla a favor del uso de las funciones locales.
fuente
Estoy de acuerdo en que los métodos largos a menudo son un olor a código, pero no creo que esa sea la imagen completa, más bien es por eso que el método es largo que indica un problema. Mi regla general es que si el código está haciendo múltiples tareas distintas, cada una de esas tareas debe ser su propio método. Para mí sí importa si esas secciones de código son repetitivas o no; a menos que esté absolutamente seguro de que nadie querría llamarlos individualmente por separado en el futuro (¡y eso es algo muy difícil de asegurar!) póngalos en otro método (y hágalo privado, lo que debería ser un indicador muy fuerte no espera que se use fuera de la clase).
Debo confesar que aún no he usado funciones locales, por lo que mi comprensión está lejos de ser completa aquí, pero el enlace que proporcionó sugiere que a menudo se usarían de manera similar a una expresión lambda (aunque aquí hay una serie de casos de uso). donde pueden ser más apropiados que lambdas, o donde no puede usar un lambda, vea Funciones locales en comparación con expresiones lambda para detalles). Aquí, entonces, creo que podría deberse a la granularidad de las "otras" tareas; si son bastante triviales, ¿tal vez una función local estaría bien? Por otro lado, he visto ejemplos de expresiones lambda gigantescas (probablemente donde un desarrollador descubrió recientemente LINQ) que han hecho que el código sea mucho menos comprensible y fácil de mantener que si se hubiera llamado simplemente desde otro método.
La página de funciones locales indica que:
No estoy seguro de que realmente esté con MS en este caso como motivo de uso. El alcance de su método (junto con su nombre y comentarios) debe dejar en claro cuál era su intención en ese momento . Con una función local, podría ver eso, otros desarrolladores pueden verlo como más sacrosanto, pero potencialmente hasta el punto en que si se produce un cambio en el futuro que requiera que se reutilice esa funcionalidad, escriben su propio procedimiento y dejan la función local en su lugar ; creando así un problema de duplicación de código. La última oración de la cita anterior podría ser relevante si no confía en los miembros del equipo para que comprendan un método privado antes de llamarlo, y por lo tanto lo llaman inapropiadamente (por lo que su decisión podría verse afectada por eso, aunque la educación sería una mejor opción aquí) .
En resumen, en general, preferiría separarme en métodos, pero MS escribió Funciones locales por una razón, por lo que ciertamente no diría que no las use,
fuente