¿Debemos cambiar el nombre de los métodos sobrecargados?

12

Supongamos una interfaz que contiene estos métodos:

Car find(long id);

List<Car> find(String model);

¿Es mejor cambiarles el nombre de esta manera?

Car findById(long id);

List findByModel(String model);

De hecho, cualquier desarrollador que use esta API no necesitará mirar la interfaz para conocer los posibles argumentos de los métodos iniciales find() .

Entonces mi pregunta es más general: ¿Cuál es el beneficio de usar métodos sobrecargados en el código ya que reduce la legibilidad?

    
pregunta Mik378 29.01.2012 - 16:08

4 respuestas

21

Este es un problema relativamente menor en comparación con muchas otras malas prácticas de legibilidad a las que podrías ser susceptible, por lo que diría que es principalmente una cuestión de gusto cómo nombras tus métodos.

Dicho esto, si vas a hacer algo al respecto, seguiría esta práctica:

  • Sobrecarga si ...

    Los métodos obedecen a casi el mismo contrato, pero simplemente operan con diferentes datos (imagine un operador de telefonía que puede buscar su cuenta por su número de identificación fiscal personal, su número de cuenta o su nombre y fecha de nacimiento). Esto incluye devolver el mismo tipo de salida .

  • Usa un nombre diferente si ...

    Los métodos hacen cosas sustancialmente diferentes o devuelven resultados diferentes (como su caso). Podría considerar usar un nombre diferente si uno accede a la base de datos y el otro no.

    Además, si el tipo devuelto es diferente, también cambiaría el verbo para indicar que:

    Car findById(long id);
    
    List findAllByModel(String model);
    
respondido por el Nicole 29.01.2012 - 16:20
4

Recomendaría usar un nombre diferente, en todos los casos. Es posible que en algún momento en el futuro, desee agregar otro método, por ejemplo, List<Car> findByMake(String make) , en contraste con List<Car> findByModel(String model) . Tan repentinamente, llamar a todo find deja de tener sentido. También es menos probable que sus métodos se utilicen de forma inadvertida si sus nombres proporcionan más información sobre cómo deben usarse.

    
respondido por el Dawood ibn Kareem 30.01.2012 - 00:20
4

Si cambia el nombre de un método, ya no se va a sobrecargar. En sí mismo, la sobrecarga no necesariamente hace que el código sea menos legible, sin embargo, puede hacer que la implementación sea más difícil de seguir si la sintaxis no es clara.

Muchos idiomas utilizan la sobrecarga de métodos como un medio para presentar una interfaz a la funcionalidad donde los parámetros pueden ser opcionales y están implícitos los valores predeterminados para los parámetros opcionales. Esto es particularmente cierto para los idiomas que no admiten una sintaxis de parámetros predeterminada en la declaración de método.

Haciendo esto:

void MyMethod(int param1, int param2 = 10)
{
    ...
}

te salva de hacer esto:

void MyMethod(int param1)
{
    MyMethod(param1, Param2Default);
}

void MyMethod(int param1, int param2)
{
    ....
}

En cuanto a lo que es más legible, realmente depende de ti. Personalmente, prefiero la segunda opción, especialmente cuando la lista de parámetros se está alargando un poco, pero supongo que no importa en la medida en que sea coherente en su API.

La dificultad con la sobrecarga se produce cuando desea funciones que hacen esencialmente lo mismo, y donde desea que las listas de parámetros sean iguales, pero los tipos de retorno sean diferentes. La mayoría de los idiomas no saben cómo diferenciar entre dos métodos con el mismo nombre, pero con diferentes tipos de devolución. En este punto, debe pensar en usar genéricos, cambiar la interfaz de parámetros o cambiar el nombre de uno de sus métodos para indicar la diferencia en el tipo de retorno. Aquí es donde la legibilidad puede convertirse en un gran problema, si no te conformas con un esquema de denominación simple y claro para hacer frente a situaciones como esta.

Nombrar sus métodos sobrecargados GetSomething() y GetSomethingEx() no va a decir mucho sobre cuáles son las diferencias entre sus métodos, particularmente si los tipos de retorno son las únicas diferencias entre ellos. Por otro lado, GetSomethingAsInt() y GetSomethingAsString() le informan un poco más sobre lo que están haciendo los métodos, y aunque no es una sobrecarga estrictamente, indican que los dos métodos hacen cosas similares, pero devuelven diferentes tipos de valores. Sé que hay otras formas de nombrar métodos, sin embargo, a los efectos de ilustrar el punto, estos ejemplos crudos deberían ser suficientes.

En el ejemplo de OP, el cambio de nombre no es estrictamente necesario porque los parámetros del método son diferentes, sin embargo, hace que las cosas sean un poco más claras para nombrar un método más específicamente. Al final, todo se reduce al tipo de interfaz que desea presentar a sus usuarios. La decisión de no sobrecargar no debe tomarse únicamente en función de su propia percepción de legibilidad. Los métodos de sobrecarga pueden, por ejemplo, simplificar una interfaz API y reducir la cantidad de métodos que un desarrollador podría necesitar recordar; por otra parte, puede ofuscar la interfaz hasta un grado que luego requiera que un desarrollador lea la documentación del método para comprender qué forma del método a utilizar, mientras que tener un número de métodos denominados de manera similar pero descriptiva puede hacer que sea más evidente simplemente leyendo un nombre de método en cuanto a su propósito.

    
respondido por el S.Robins 30.01.2012 - 04:51
0

Favorece la sobrecarga siempre que los métodos devuelvan lo mismo y sigan el mismo contrato. La sobrecarga libera el código de llamada de la confirmación innecesaria del tipo de parámetro.

Supongamos que la función de llamada recibe una consulta de búsqueda como parámetro y realiza algún otro procesamiento antes y / o después de la llamada a find .

void tryToSellCars(String which) {
    /* grab an airhorn, inflatable tube guy... */
    List<Car> cars = find(which);
    /* expound virtues of each car in detail... */
}

Si desea cambiar el tipo de esa consulta por cualquier motivo en el futuro (por ejemplo, de una cadena de ID simple a un objeto de consulta con todas las funciones de algún tipo) puede realizar ese cambio en la función de llamada simplemente cambiando la firma de la función para aceptar el nuevo tipo de parámetro sin preocuparse por cambiar el método que invoca en su clase.

void tryToSellCar(CarQuery which) {
    /* grab airhorn, inflate tube guy... */
    List<Car> cars = find(which)
    /* expound virtues of each car in detail... */
}

Si implementas findById y findByQueryObject por separado, deberías rastrear cada llamada para hacer ese cambio. En el ejemplo, solo cambié una palabra y terminé.

    
respondido por el sqykly 29.10.2013 - 16:34

Lea otras preguntas en las etiquetas

Comentarios Recientes

La implementación documentada de sobrecarga de funciones no devuelve llamadas a la función. Pero llamar al método sobrecargado ya no devuelve el contenido de la lista de argumentos (es decir, el resultado de llamar al método sobrecargado), sino más bien el objeto en sí (si se pueden encontrar). Pero esta no sería la historia si no fuera útil. En principio, todos los datos en el cuerpo de una función pueden ser pasados y recuperados por esa función. Por lo tanto, los métodos sobrecargados introducen más ambigüedad... Lee mas