Pregunta

El estándar .NET de prefijar un nombre de interfaz con un I parece generalizarse y ya no se limita a .NET. Me he encontrado con mucho código Java que usa esta convención (por lo que no me sorprendería si Java lo usara antes que C #). También Flex lo usa, y así sucesivamente. Sin embargo, la colocación de una I al comienzo del nombre huele a notación húngara, por lo que me siento incómodo con su uso.

Entonces, la pregunta es, ¿existe una forma alternativa de denotar que Something es una interfaz, en lugar de una clase y hay alguna necesidad de denotarlo de esta manera? ¿O es un caso que se ha convertido en un estándar y, por lo tanto, debería aceptarlo y dejar de tratar de provocar "guerras religiosas"? ¿sugiriendo que se haga de manera diferente?

¿Fue útil?

Solución

Del libro de Pautas de diseño del marco:

  

Las interfaces que representan las raíces de una jerarquía (por ejemplo, IList) también deben usar sustantivos o frases nominales. Las interfaces que representan capacidades deben usar adjetivos y frases adjetivas (por ejemplo, IComparable, IFormattable).

Además, a partir de las anotaciones sobre el nombre de la interfaz:

  

KRZYSZTOF CWALINA: uno de los pocos   los prefijos utilizados son & # 8220; I & # 8221; para interfaces   (como en ICollection), pero eso es para   razones históricas En retrospectiva, yo   creo que hubiera sido mejor usar   nombres de tipo regulares En la mayoría de   los desarrolladores de casos no les importa que   algo es una interfaz y no un   clase abstracta, por ejemplo.

     

BRAD ABRAMS: Por otro lado, el & # 8220; I & # 8221; prefijo en las interfaces es un claro   reconocimiento de la influencia de COM   (y Java) en .NET Framework. COM   popularizado, incluso institucionalizado,   la notación de que comienzan las interfaces   con & # 8220; I. & # 8221; Aunque discutimos   divergiendo de este patrón histórico   decidimos llevar adelante el   patrón como muchos de nuestros usuarios eran   Ya estoy familiarizado con COM.

     

JEFFREY RICHTER: Personalmente, me gusta el   & # 8220; I & # 8221; prefijo y ojalá tuviéramos más   Cosas como esta. Pequeño personaje   los prefijos ayudan mucho a mantener   código breve y sin embargo descriptivo. Como yo   dicho anteriormente, uso prefijos para mi   campos de tipo privado porque encuentro   esto es muy útil.

     

BRENT RECTOR Nota:   esta es realmente otra aplicación de   Notación húngara (aunque una sin   las desventajas de la notación   usar en nombres de variables).

Se ha convertido en un estándar ampliamente adoptado, y aunque es una forma de húngaro, como dice Brent, no tiene las desventajas de usar la notación húngara en nombres de variables.

Otros consejos

Simplemente lo aceptaría, para ser honesto. Sé lo que quieres decir con ser un poco como la notación húngara (o al menos abusar de la misma), pero creo que da el valor suficiente para que valga la pena hacerlo en este caso.

Con la inyección de dependencia en boga, a menudo encuentro que termino con una interfaz y una única implementación de producción. Es útil hacerlos fácilmente distinguibles solo con el prefijo I.

Un pequeño punto de datos: trabajo con Java y C # una cantidad considerable, y regularmente me encuentro teniendo que verificar qué tipos de Java son realmente interfaces, particularmente en torno al marco de recopilación. .NET simplemente hace esto simple. Tal vez no molesta a otras personas, pero me molesta.

+1 para IFoo de mi parte.

Como programador .NET (en su mayor parte), en realidad prefiero la convención de Java de soltar el I aquí, por una simple razón: a menudo, los rediseños pequeños requieren el cambio de una interfaz a una clase base abstracta o viceversa. Si tiene que cambiar el nombre, esto podría requerir una refactorización innecesaria.

Por otro lado, el uso para el cliente debe ser transparente, por lo que no debe preocuparse por este tipo de sugerencia. Además, el sufijo "capaz" en "Thingable" debería ser suficiente pista. Funciona bastante bien en Java.

/ EDITAR: Me gustaría señalar que el razonamiento anterior me ha llevado a eliminar el prefijo I para proyectos privados. Sin embargo, al comparar uno de ellos con el conjunto de reglas FxCop, rápidamente volví al uso de I . La coherencia gana aquí, aunque una tonta consistencia es el duende de las mentes pequeñas .

Se trata de estilo y legibilidad . Prefijo de interfaces con " I " es simplemente una convención de nomenclatura y una guía de estilo que se ha puesto de moda. A los compiladores no les importa menos.

El estándar de codificación para Symbian tiene interfaces (clases abstractas C ++ abstractas) indicadas con una M en lugar de una I.

De lo contrario, la única otra forma que he visto de denotar interfaces es a través del contexto.

Para .NET, el libro de Pautas de Diseño de Marco de Microsoft lo recomienda absolutamente, y sí, es muy estándar. Nunca lo había visto hecho de otra manera, y crear una nueva convención solo serviría para confundir a las personas.

Debo agregar que tampoco me gusta la notación húngara, pero este y el caso de prefijar variables de clase con un guión bajo son buenas excepciones para mí, porque hacen que el código sea mucho más legible.

Siempre he pensado que esta convención de nombres es un poco un dinosaurio. Hoy en día, los IDE son lo suficientemente potentes como para decirnos que algo es una interfaz. Agregando que hace que el código sea más difícil de leer, por lo que si realmente desea tener una convención de nomenclatura que separe las interfaces de las clases, agregaría Impl al nombre de la clase implementadora.

public class CustomerImpl implements Customer

Usted solicitó una alternativa, así que aquí hay una que he encontrado:

Use el prefijo no en la clase de interfaz, pero use el prefijo c o C en las clases concretas correspondientes. La mayor parte de su código generalmente hará referencia a la interfaz, entonces, ¿por qué contaminarlo con el prefijo y no con el tipo de hormigón generalmente menos utilizado?

Este enfoque introduce una inconsistencia en que algunos tipos concretos serán prefijados (los que tienen interfaces coincidentes) y otros no. Esto puede ser útil ya que les recuerda a los desarrolladores que existe una interfaz y su uso debe preferirse sobre el tipo concreto.

Para ser honesto, I uso el prefijo en la interfaz, pero creo que es más porque me he acostumbrado y estoy tan cómodo con él.

Mi suposición principal es que lo más importante es mantener la legibilidad en la parte del dominio de la implementación. Por lo tanto:

  • Si tiene un comportamiento y una implementación posible, simplemente no cree una interfaz:

    clase pública StackOverflowAnswerGenerator {}

  • Si tiene un comportamiento y muchas implementaciones posibles, entonces no hay problema y simplemente puede soltar el "I" y tener:

    interfaz pública StackOverflowAnswerGenerator {}

    clase pública StupidStackOverflowAnswerGenerator: StackOverflowAnswerGenerator {}

    clase pública RandomStackOverflowAnswerGenerator: StackOverflowAnswerGenerator {}

    clase pública GoogleSearchStackoverflowAnswerGenerator: StackOverflowAnswerGenerator {}

    //...

  • El verdadero problema surge cuando tiene un comportamiento y una implementación posible, pero necesita una interfaz para describir su comportamiento (por ejemplo, para realizar pruebas convenientes, debido a la convención en su proyecto, utilizando alguna biblioteca / marco que refuerza esto , ...). Las posibles soluciones, otras de prefijar la interfaz son:

    a) Prefije o sufija la implementación (como se indica en algunas otras respuestas en este tema)

    b) Use un espacio de nombres diferente para la interfaz:

    espacio de nombres StackOverflowAnswerMachine.Interfaces { interfaz pública StackOverflowAnswerGenerator {} }

    espacio de nombres StackOverflowAnswerMachine {   clase pública StackOverflowAnswerGenerator: Interfaces.StackOverflowAnswerGenerator {} }

    c) Use un espacio de nombres diferente para la implementación:

    espacio de nombres StackOverflowAnswerMachine { interfaz pública StackOverflowAnswerGenerator {} }

    espacio de nombres StackOverflowAnswerMachine.Implementations { clase pública StackOverflowAnswerGenerator: StackOverflowAnswerMachine.StackOverflowAnswerGenerator {} }

Actualmente estoy experimentando con la última posibilidad. Tenga en cuenta que en el archivo fuente de implementación todavía puede tener " usando StackOverflowAnswerMachine; " y tener acceso conveniente a los objetos de dominio.

ACTUALIZACIÓN: Aunque todavía creo que la última posibilidad es la más limpia, su único inconveniente es que a pesar de que "usar StackOverflowAnswerMachine;" le da acceso a todos los objetos de dominio, debe prefijar todas las interfaces de dominio para no confundirlas con sus implementaciones Puede parecer algo no muy conveniente, pero en un diseño limpio, por lo general, una clase no usa muchos otros objetos de dominio, y sobre todo necesita usar el prefijo solo en la declaración de campo y la lista de parámetros del constructor. Entonces, esa es mi recomendación actual.

El cliente de la funcionalidad del dominio no debería necesitar saber si está utilizando una interfaz, una clase abstracta o una clase concreta. Si necesitan saber esto, entonces hay algún problema serio en un proyecto de este tipo, porque tiene problemas de lógica de dominio e infraestructura mezclados en la misma capa de abstracción. Por lo tanto, recomiendo " a " o " c " soluciones.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top