2011-03-10 12 views
14

vi en una aplicación donde tuvo interfaces como:¿Cómo obtener nombres de interfaz más claros?

IHasContent 
IHasValue 
IHasMesh 
IHasGeometry 
IHasTransformation 

en caso de que no sea ?:

IHaveContent 
IHaveValue 
... 

O ?:

IIncludeContent 
IIncludeValue 
... 

Personalmente estoy inclinando hacia acaba haciéndolos:

IContent 
IValue 
IMesh 
IGeometry 
ITransform 

Porque no es ISomething ya implica que tiene ese something?

En cuanto a la última, ¿debería hacerla en cambio ITransformable?

Creo que el uso de I + (Has/Have/Include/Exist, etc) + Name hace que los nombres de la interfaz sean más confusos.

¿Alguna idea sobre cómo obtener mejores nombres de interfaz que no se sienta incómodo, va al grano y tiene sentido?

Respuesta

24

Algunos de estos nombres (Contenido, Valor, etc.) son imprecisos, y hacen poco por describir el contenido/comportamiento de un elemento. En general, los nombres deben ser tan específicos y distintos como sea posible: IScriptParameter puede ser más descriptivo que IValue. A medida que su proyecto crezca, tener nombres más descriptivos hará que sus tipos sean mucho más fáciles de distinguir (si no tiene cuidado, podría terminar con IValue e INumber y IAmount para manejar variaciones de "valores")

Si su interfaz (por ejemplo, IMesh) significa que "proporciona las propiedades de una malla", entonces IMesh es un nombre perfectamente correcto: describe el hecho de que puedes tratar el objeto como si fuera una Malla.

Si su interfaz se utiliza para aplicar una acción (por ejemplo, para representar el objeto como una malla, o para aplicar una transformación al objeto), considere usar un verbo/adjetivo en lugar de nombres (por ejemplo, IRenderable, ITransformable) - este es un patrón común en .net (IEnumerable (verbo/adjetivo) en lugar de ICollection (sustantivo), por ejemplo)

Para mí, "IHasMesh" suena más como IMeshContainer - es decir, es un objeto que contiene un malla, y la interfaz me permite "obtener la malla". Por lo tanto, no me permitiría actuar o consultar datos dentro de la malla, sino que simplemente buscaría un objeto Mesh completo a través de la interfaz.

Así me gustaría utilizar:

  • ITransformable si el objeto puede transformarse través de la interfaz
  • iTransform si el objeto se puede utilizar directamente como si se trata de una Transformada de
  • IHasTransform/ITransformContainer/ITransformProvider si el objeto es un contenedor que se puede consultar para extraer un objeto Transform
8

Lo primero que debe entender es que la "I" en los nombres no se refiere al pronombre "I", sino que sigue el estándar de nomenclatura que las interfaces comienzan con la letra mayúscula "I."

En ese sentido, las interfaces se llaman realmente "HasContent", "HasValue", etc., por lo que no lo cambie a "HaveContent" y "HaveValue", ya que sería igual de incómodo.

Dicho esto, no puedo ver exactamente para qué se utilizan estas interfaces. Una interfaz (por definición) está destinada a forzar una condición en todas las clases que la implementan, y no estoy seguro de qué se están imponiendo estas interfaces, ¿que todas las clases tienen una función llamada HasContent()?

Creo que debería centrarse en las interfaces que tienen una relación is a. Cuando declara una clase que implementa la interfaz IList, no está implicando que su clase tenga una lista, sino que su clase es una lista.

Así, por ejemplo, uno de ellos es IHasGeometry ... bueno, eso me da la posibilidad de comprobar si tiene la geometría, pero sólo sería realista quieren tratar con figuras que son figuras geométricas, por lo que lo haría cree una interfaz llamada IGeometricFigure en su lugar, restringiendo así su uso a cualquier cosa que opere en figuras geométricas.

Estoy de acuerdo en que los nombres suenan incómodos, pero creo que eso se debe más a que estas interfaces se utilizan con un propósito incómodo, no porque se las nombre incorrectamente.

+0

"Una interfaz (por definición) tiene por objeto forzar una condición en todas las clases que la implementan, y no estoy seguro de qué se están aplicando estas interfaces" - Creo que es inútil especular o juzgar la elección del identificador sin conociendo el modelo de dominio subyacente. –

+0

@ O.R.Mapper ... y eso importa ... ¿por qué? – riwalk

+0

Bueno, como no conoce el modelo de dominio subyacente, el hecho de que "no esté seguro de lo que estas interfaces están haciendo cumplir" es irrelevante y no implica que las interfaces estén mal nombradas. –

12

Personalmente, me gusta IHas + Word porque el nombre de la interfaz describe una propiedad de las clases que las implementan. Por ejemplo:

public class Lolcat : IHasCheezburger 

Cuando leí que fácilmente entender que lolcats tienen hamburguesas con queso en ellos.

Por otro lado,

public class Lolcat : ICheezburger 

hace que me pregunte si lolcats TIENEN hamburguesas con queso o SON hamburguesas con queso (que es el verbo tradicional utilizado en la interpretación de la herencia).

+5

No sé si reír o estoy de acuerdo ... :) – riwalk

+0

Gracias pero Stargazer también dijo que el 'I' no se refiere al pronombre' I', sino solo a un prefijo. Pero no estoy seguro si eso es universalmente aceptado. –

+1

@Joan definitivamente es universalmente aceptado. –

4

Su lista inicial de nombres de interfaz parece exactamente correcta. Un nombre de interfaz debe describir el contrato. Por ejemplo, esta es una interfaz que encontré recientemente que me gustó bastante:

public interface IDeterminesEmptyValue 
{ 
    bool IsEmpty { get; } 
} 

¡Perfecto! El nombre lo dice todo. La "I" se refiere al hecho de que es una interfaz, y el resto describe lo que cumplirá el contrato.

Si la interfaz se llamó IEmptyValue, significa que la interfaz garantiza que el implementador ES un valor vacío. No lo es - tiene la capacidad de determinar si un valor está vacío.

(Probablemente) ninguna clase se llamaría DeterminesEmptyValue. Pero podría haber mil clases que tengan la capacidad de determinar si los diferentes tipos de valores están vacíos, y esta interfaz les permite a todos ser llamados de una manera común.

La interfaz debe describir claramente una característica específica de las clases que la implementan. En el caso de IContent - ¿los implementadores TIENEN contenido, o los implementadores SON contenido?

+0

¿Pero no sería mejor si fuera IEmptyValue? –

+0

Porque en una de las respuestas, Carra dice "Los nombres deberían diferir solo por la letra I prefijo en el nombre de la interfaz". Entonces, si esto fuera una clase, nadie lo llamaría 'class DeterminesEmptyValue', ¿verdad? –

+0

@Joan 'IEmptyValue' significa que la interfaz garantiza que el implementador ES un valor vacío. No lo es, tiene la capacidad de determinar si un valor está vacío. Ninguna clase se llamaría 'DeterminesEmptyValue', pero podría haber un millar de clases que tienen la capacidad de determinar si los diferentes tipos de valores están vacíos, y esta interfaz les permite a todos ser llamados de una manera común. –

1

La "I" no significa "yo". Solo significa Interface.

Pero Microsoft tiene su own guidelines para nombrar interfaces.

Los nombres deben diferir solo por el prefijo de letra I en el nombre de la interfaz.

4

me gusta pensar que ISomething significa que es Algo, como en el juego de rol de algo, en lugar de que 'tiene' o 'incluye' Alguna cosa. Por lo tanto, IFather significa 'Yo hago el papel de padre', o yo soy el padre '. IDispatcher significa 'Tengo un rol de Dispatcher' o 'Soy despachador', etc.

A algunas personas les gusta nombrar interfaces para responder una pregunta '¿qué hago?' : IListenForEvents, ILogExceptions. Like in this post

+0

O tal vez responda a la pregunta '¿Qué es usted?': 'IEventListener',' IEventLogger' – orad

3

Las interfaces se utilizan para muchos propósitos, con diferentes convenciones de nomenclatura confusas. Antes de preocuparse por los nombres, probablemente sea bueno primero decidir cómo segregar la funcionalidad. Desafortunadamente, las colecciones de Microsoft tienen muy pocas interfaces distintas, las mayores omisiones son IReadableList e IAppendable, ambas pueden ser heredadas por IList pero soportan la contravariancia y la covarianza [para que uno pueda pasar un IList (de Cat) al código esperando una IReadableList (de Animal) o un IAppendable (Of SiameseCat)]. Por otro lado, también es posible dividir las cosas demasiado finamente, por lo que cualquier clase útil debe implementar docenas de interfaces.

Sin saber qué tipos de funcionalidad se utilizaron en la aplicación y las interfaces, es difícil decir si fueron diseñadas con un buen nivel de granularidad. Parece que están muy finamente divididos, pero realmente no puedo decirlo. Una vez que la funcionalidad se agrupa adecuadamente, entonces tiene sentido preocuparse por el nombre.

+0

Gracias supercat, esa es una idea interesante. ¿Crees que MS hizo esto por motivos de rendimiento? ¿Te gustaría tener 5 interfaces en lugar de una, lo que podría ralentizar la inicialización, etc.? –

Cuestiones relacionadas