2011-11-21 17 views
5

En términos de buenas prácticas de codificación de Objective-C, si creo una función que no tiene estado, ¿es mejor escribirla como un método estático de alguna clase o como un Función C?Métodos estáticos sin estado vs. funciones C en Objective-C

Por ejemplo, tengo un método de recuperación de ruta de archivo especial que comprueba el directorio de Caches antes de proceder al NSBundle principal. Actualmente lo tengo como un método estático en una clase de Utils vacía. ¿Debería ser esto una función C?

La razón por la que he elegido usar un método estático (por ahora) es que a) es consistente con la sintaxis de Objective-C, yb) la clase ayuda a categorizar el método. Sin embargo, siento que estoy haciendo trampa un poco, ya que podría llenar fácilmente mi clase Util con estos métodos estáticos sin estado y terminar con una fea "clase shell", cuyo único propósito sería retenerlos.

¿Qué convención usas? ¿Es uno "mejor" que el otro, por alguna medida objetiva? ¡Gracias!

Respuesta

2

Si puede pensar en una clase existente que podría ser un buen método, puede inyectar su método haciendo una categoría Objective-C. Esto mantiene sus dos razones para usar un método estático sin contaminar el espacio de clase con una clase adicional.

Por ejemplo:

@interface NSString (MyStringCategories) 
- (NSString*) myCoolMethod; 
@end 

// [StringCategories.m] 
#import "StringCategories.h" 

@implementation NSString (MyStringCategories) 
- (NSString*) myCoolMethod { 
    // do cool stuff here 
    return whateverYouLike; 
} 
@end 

Ahora usted puede enviar myCoolMethod-cualquier cadena. ¡Guay!

En su caso particular, parece que un método en NSBundle podría ser una arquitectura apropiada. Y no lo olvide, puede ser un método de clase, por lo que no necesita instanciar nada para llamar a su método.

+0

Sí, trato de hacer eso tan a menudo como sea posible. Sin embargo, no pude pensar en uno en este caso: solo busca en el paquete si no encuentra el archivo en Caches, y no es un método de instancia como el pathForResource típico, por lo que (en mi opinión) no es un ajuste ideal. – Archagon

+0

Así que conviértalo en un método de clase. Mi punto es, ¿no es la incapacidad de pensar en una clase existente apropiada solo un fracaso de la imaginación? Podría ser NSBundle, podría ser NSFileManager, podría ser NSString (porque trata con nombres de rutas), podría ser de cualquier clase _you intuitivamente se siente en el estadio correcto. – matt

+0

+1 Para la categoría. Personalmente creo que el propósito de una clase es ser instanciado. No use una clase como espacio de nombres. Entonces, si solo tienes métodos estáticos, debes considerar otro enfoque. – Macmade

1

Esta es una pregunta bastante difícil de responder porque para muchas personas la respuesta dependerá de cuáles sean sus preferencias y gustos personales. Personalmente, creo que si tienes una función que es una función, es decir, no tiene nada que ver con un objeto, no tiene un estado interno, etc. pp. Por favor, deja que sea una función y no intentes envolver todo lo que puedas en un objeto solo porque estás usando un idioma OO y puedes.

Con el fin de mantener mi respuesta corta me referiré a un (OMI) muy buen libro:

http://www.gotw.ca/publications/c++cs.htm

sé que esto es para C++, pero hay un buen número de ideas que pueden compartido con otros lenguajes (especialmente Objective-C y Objective-C++) especialmente de la parte llamada "Class Design and Heurence". Allí encontrará un elemento titulado "Prefiero escribir funciones nonfriend no miembro".

En pocas palabras: "funciones no-amigo no socios mejorar la encapsulación, reduciendo al mínimo las dependencias [...] También se rompen clases aparte monolíticos [...] [y] mejorar la generalidad [...]".

Creo que hay algo de verdad en ese artículo.

1

Si no hay una clase para vincular claramente, entonces uso una función. También utilizo funciones para estos bits de utilidad porque pueden ser eliminados si no se usan o no se referencian. En ese sentido, también es útil usar una función porque un error de enlace es mejor que un error de tiempo de ejecución (incluso en el .m se omitió accidentalmente en la compilación, o si se hizo referencia a él desde otro método actualizado externamente).Un problema con los símbolos ObjC es que no se eliminan, por lo que tienen una gran cantidad de dependencia: todos los métodos y clases de objc, y los métodos de categoría requeridos deben existir en el binario final. Eso no es un problema con programas o bibliotecas realmente pequeños, pero gana peso rápidamente con sistemas y bibliotecas medianas/grandes.

No es necesario declarar todo en un @interface, especialmente con sistemas más grandes donde todas esas declaraciones realmente convertirán sus interdependencias en espagueti. En comparación con los métodos, las funciones son más rápidas, más pequeñas, pueden ser optimizadas mejor por el compilador o durante la vinculación, y pueden ser eliminadas si no se hace referencia a ellas.

Si necesita polimorfismo, simplemente pertenece a una clase por organización o conveniencia, entonces una clase o método de instancia a menudo es una mejor opción.

También minimizo la declaración de métodos de categoría por las mismas razones. Cuando usa funciones, puede escribir fácilmente un método de envoltura donde lo necesite y obtener lo mejor de ambos mundos.