2010-05-09 10 views
9

He aquí un ejemplo de un método de utilidad:Método de utilidad: ¿pasar un archivo o una cadena?

public static Long getFileSize(String fileString) { 

    File file = new File(fileString); 

    if (file == null || !file.isFile()) 
     return null; 

    return file.length(); 
} 

¿Es una buena práctica para pasar una cadena en lugar de un archivo a un método como este? En general, ¿qué razonamiento se debe aplicar al hacer los métodos de utilidad de este estilo?

+3

Si están haciendo un 'Archivo' primero, no creo que se molesten en hacer' getFileSize (file) 'cuando podrían hacer' file.length() '. Además, 'file' no puede ser' null' en esa situación; los constructores no tienen la capacidad de devolver un objeto nulo, tendría que ser un método de fábrica como 'File makeFile (String filename)' –

Respuesta

3

Ésta es mi solución preferida:

public static Long getFileSize(String path) { 
    return getFileSize(new File(path)); 
} 

public static Long getFileSize(File file) { 
    return (!file.isFile()) ? -1L : file.length(); 
} 

Nota que está regresando 1L en lugar de 0L, para permitir que la persona que llama para distinguir entre un archivo vacío, y un "archivo" cuya longitud no puede ser determinada por alguna razón. El file.length() devolverá cero en algunos casos donde no tiene un archivo de longitud cero; p.ej.

  • cuando el file no existe
  • cuando el file es un directorio
  • cuando el file es un archivo especial (por ejemplo, archivo de dispositivo, tubería, etc.) y el sistema operativo no se puede determinar su longitud.

La llamada file.isFile() se ocupa de estos casos. Sin embargo, es discutible si los métodos deben devolver -1L o lanzar una excepción. La respuesta a este debate depende de si los casos -1L son "normales" o "excepcionales", y eso solo se puede determinar con referencia a los contextos en los que se diseña el método,

0

Lo único que importa es cómo vas a utilizar este método. En otras palabras, si su aplicación opera con objetos File, podría pasarlos y eliminar algunas operaciones innecesarias. Si opera con rutas de archivos, el parámetro de cadena puede ser más conveniente.

Pero, en última instancia, ninguna de las dos opciones es incorrecta: ninguna de las dos cosas empeorará la aplicación.

1

Creo que esto dependerá de lo que tenga disponible en el momento en que va a llamar a este método. Si tiene el nombre del archivo (Cadena), pero no el Archivo, no tiene mucho sentido hacer que la persona que llama cree el Archivo a partir del nombre del archivo.

Mi enfoque para esto cuando no estoy seguro es crear dos métodos, uno para Cadena, uno para Archivo. Luego, haga que String one cree el archivo y llame al archivo uno.

public static long getFileSize (final String fileString) { 
    return getFileSIze (new File (fileString)); 
} 

public static long getFileSize (File file) { 
    if (file == null || !file.isFile()) return null; 
    return file.length(); 
} 
1

Depende de la utilidad esperada del lado del cliente. En caso de que el lado del cliente ya tenga un objeto de archivo y desee recuperar el tamaño del archivo, el desarrollador del lado del cliente se ve obligado a extraer la ruta del archivo y pasarla al método de utilidad. Para evitarlo, proporcionaría métodos sobrecargados 1) con Archivo 2) Cadena de ruta de archivo

Además, en caso de que el archivo no esté disponible, lanzaría una excepción que devolvería nulo.

+0

No hay ventaja en sobrecargar aquí, use nombres distintos a menos que haya alguna justificación. http://stackoverflow.com/questions/248222/method-overloading-can-you-overuse-it – leonbloy

+0

@leonbloy - ¿Qué consideraría una justificación? Por ejemplo, en la pregunta que enlazó, la respuesta aceptada recomienda explícitamente sobrecargas para, entre otras cosas, el nombre del archivo como cadena y el Archivo. – CPerkins

+0

@CPerkins: vea mi respuesta a binil, y la cita de Joshua Bloch. La sobrecarga de métodos (con el mismo número de parámetros) es la raíz de muchos males especialmente cuando: los tipos alternativos son una subclase de otra o cuando se usan en setters (o en métodos generales que algunos framework buscarán en tiempo de ejecución a través de la reflexión). Estoy de acuerdo en que estos factores agravantes no se aplican aquí, pero de todos modos, soy conservador al respecto, y no estoy de acuerdo con esa recomendación. – leonbloy

1

Mi recomendación sería tener tanto:

public static Long getFileSize(String path) { 
    return getFileSize(new File(path)); 
} 

public static Long getFileSize(File file) { 
    return (file == null || !file.isFile()) ? 0L : file.length(); 
} 

y que sus usuarios puedan seleccionar en función del tipo de objeto que están utilizando para representar vías de acceso del sistema de archivos. Como @Nikita mencionó, ninguna de las opciones es incorrecta.

+2

Te daría +1 ... si no fuera por la prueba 'file == null'. Ese caso es un error de diseño en el método original ... debería permitir que ocurra una NPE). También debería devolver -1L en vez de 0L para "no es un archivo" para distinguir el caso de un archivo con cero bytes. –

+1

@Stephen Sí, estoy de acuerdo con todo ...a excepción de la parte +1. :-) –

+0

La sobrecarga de métodos se usa con demasiada frecuencia, y este es un ejemplo. No hay nada que ganar (excepto algún dolor futuro) llamando a los dos métodos iguales en este caso. Lea aquí http://stackoverflow.com/questions/248222/method-overloading-can-you-overuse-it – leonbloy

1

En mi opinión, esa función solo es útil con un parámetro de cadena. ¿Qué hace?

  • Crea un objeto de archivo.
  • Comprueba que se puede crear.
  • Los cheques que se trata de un archivo
  • Devuelve la longitud

Si pasa un archivo, no es necesario que lo primero, los dos siguientes, probablemente, se debe asumir, y la longitud es un miembro de archivo función. Si pasa esto un fichero, esta función se vuelve demasiado trivial para escribir :)

(Además, creo que volver nula a partir de una función que devuelve un largo que es extraño)

Si usted tiene un objeto de archivo ya, el uso :

length = file.isFile() ? file.length() : -1; 

Si sus ofertas de código con archivos en lugar de nombres de archivo que usted podría ahorrar un poco de archivo se abre si vuelve a utilizar los punteros de archivos. En ese caso, podría llevarlo a usarlos sobre el enfoque de nombre de archivo.

+0

¡Ese código no abre archivos! Crea un "envoltorio de cadenas elegante" (el objeto 'Archivo') y lo usa para buscar el archivo en el sistema de archivos (en' isFile() 'y' length() '). Como la búsqueda es nativa, no veo si se puede ahorrar tiempo o recursos al reutilizar el objeto 'Archivo'. –

+0

@Christian Semrau: No estoy muy familiarizado con Java, gracias por señalarlo. Aparentemente, File() no realiza una llamada al sistema. Pero isFile & length ambos resultan en llamadas al sistema (¿verdad?). Si está trabajando con objetos de archivo en otro lugar, es posible que ya sepa si se ha llamado a File ... es probable que no desee que todo su código compruebe isFile() y maneje los directorios de manera diferente. (respuesta fija) – Stephen

1

Hay una serie de existen

  1. métodos de utilidad para reducir la cantidad de código placa de la caldera repetitivo en su aplicación, por lo tanto haciendo que el código más legible y reducir el número de errores potenciales: consideraciones. Tiene sentido atender los patrones de uso más comunes, es decir, si la mayoría de las veces tiene una cadena que describe un archivo, pase la cadena. La mayor parte del beneficio proviene de tener un método de utilidad en primer lugar, no obtener la firma óptima que es 100% a prueba de futuro.

  2. Pasar un archivo en lugar de una cadena proporciona un tipado más fuerte, es decir, puede verificar más código en tiempo de compilación para evitar errores tipográficos. Haga que el compilador haga el trabajo por usted, use los beneficios de una escritura fuerte.

  3. Pasar un archivo significa que puede pasar cualquier tipo de objeto File, posiblemente un objeto de archivo en memoria personalizado sin tener que cambiar el método de utilidad para manejar el descriptor de archivo personalizado.

  4. Pasar una cadena puede ser útil cuando tiene que tratar mucho con las rutas de archivos del sistema operativo y solo quiere verificar el tamaño con un número mínimo de líneas.

  5. Al final puede tener varios métodos de utilidad sobrecargados a un costo muy bajo. Este escenario es exactamente el motivo de la existencia de sobrecarga de método como característica de idioma. Vea lo que naturalmente funciona en su base de código. El código es maleable y esta no es una de estas decisiones de diseño con la que tendrías que vivir para siempre, a menos que estés creando una API para que otras personas la utilicen.

  6. También puede que desee cambiar el nombre a ser un poco más descriptivo, por ejemplo

    • largo sizeFromFile (File f) y
    • largo sizeFromFileName (String name)

    usando la convención originalmente suggested by Joel Spolsky.

2

me gustaría ir con un archivo. Se siente un pequeño OOP correcto para mí: más typesafe (Strings son tan 'generales' en Java ...) y semánticamente expresivo: si se trata de archivos, entonces pase un objeto File.

Recordemos que en Java un objeto El archivo no representa realmente un archivoen sí mismo (su contenido), sino más bien a su paso: "An abstract representation of file and directory pathnames" (que incluso puede ser la ruta de un archivo inexistente) y eso es casi exactamente lo que necesitas aquí.

Esto solo puede ser una limitación en algunos casos: si el "archivo" es realmente algún tipo de pseudo-archivo o recurso, por ejemplo dentro de un archivo jar. Una alternativa que he encontrado útil es un URI, que (conceptualmente) incluye un archivo como un caso especial, pero también otros recursos.

Y si decide seguir con las dos alternativas (Cadena o Archivo), no le recomiendo enfáticamente nombrar los métodos de la misma manera. Method overloading can be a pain, úsela solo cuando le proporcione un beneficio tangible.

1

Método La sobrecarga es la mejor práctica en tales casos.

Cuestiones relacionadas