Suponga 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 find()
métodos iniciales .
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?
Respuestas:
Este es un problema relativamente menor en comparación con muchas otras prácticas de mala legibilidad a las que podría ser susceptible, por lo que diría que es principalmente una cuestión de gusto cómo nombra sus métodos.
Dicho esto, si vas a hacer algo al respecto, seguiría esta práctica:
Sobrecarga si ...
Los métodos obedecen casi el mismo contrato, pero simplemente operan con entradas diferentes (imagine un operador telefónico 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 .
Use un nombre diferente si ...
Los métodos hacen cosas sustancialmente diferentes o devuelven resultados diferentes (como su caso). Puede 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:
fuente
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 conList<Car> findByModel(String model)
. Entonces, de repente, llamar a todofind
deja de tener sentido. También es menos probable que sus métodos se usen incorrectamente sin darse cuenta, si sus nombres dan más información sobre cómo deben usarse.fuente
find(Make val)
yfind(Model val)
. Entonces, los métodos de conveniencia, comofindByMake(String val)
sería mucho más claro lo que realmente están haciendo. Después de todo, aString
no es una marca o un modelo, por lo que el método debería explicar lo que realmente está haciendo.Si cambia el nombre de un método, ya no se 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 lenguajes usan la sobrecarga de métodos como un medio para presentar una interfaz a la funcionalidad donde los parámetros pueden ser opcionales y los valores predeterminados para los parámetros opcionales están implícitos. Esto es particularmente cierto para los idiomas que no admiten una sintaxis de parámetros predeterminada en la declaración del método.
Entonces haciendo esto:
te salva de hacer esto:
En cuanto a cuál es más legible, eso realmente se reduce a usted. Personalmente, prefiero la segunda opción, especialmente cuando la lista de parámetros se está alargando un poco, pero supongo que en realidad no importa siempre que sea coherente en toda 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 las mismas, 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 retorno. 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 se conforma con un esquema de nombres simple y claro para hacer frente a situaciones como esta.
Nombrar sus métodos sobrecargados
GetSomething()
yGetSomethingEx()
no va a decir mucho sobre cuáles son las diferencias entre sus métodos, especialmente si son los tipos de retorno las únicas diferencias entre ellos. Por otro lado,GetSomethingAsInt()
yGetSomethingAsString()
contarle un poco más sobre lo que están haciendo los métodos, y aunque no es estrictamente una sobrecarga, sí indica 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, para ilustrar el punto, estos ejemplos crudos deberían servir.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 basarse únicamente en 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 puede necesitar recordar, por otro lado, puede ofuscar la interfaz en un grado que luego requiere que un desarrollador lea la documentación del método para comprender qué formulario del método a usar, mientras que tener una cantidad de métodos nombrados 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.
fuente
Favorezca la sobrecarga siempre que los métodos devuelvan lo mismo y sigan el mismo contrato. La sobrecarga libera el código de llamada de comprometerse innecesariamente con el tipo de parámetro.
Suponga 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
.Si desea cambiar el tipo de esa consulta por cualquier motivo en el futuro (por ejemplo, desde una cadena de identificación simple a un objeto de consulta con todas las funciones de algún tipo), puede hacer ese cambio en la función de llamada simplemente cambiando la firma de la función aceptar el nuevo tipo de parámetro sin preocuparse por cambiar el método que llama en su clase.
Si implementa
findById
y porfindByQueryObject
separado, tendría que buscar cada llamada para realizar ese cambio. En el ejemplo, solo cambié una palabra y terminé.fuente
findByFoo
para detectar desajustes de tipo anteriormente.