naming conventions - multiple - ¿Existen alternativas establecidas para ISomething/ISomethingable para interfaces?
java package naming conventions singular or plural (9)
El estándar .NET de prefijar un nombre de interfaz con un I parece estar extendiéndose y ya no se limita a .NET. He encontrado una gran cantidad de código Java que usa esta convención (por lo que no me sorprendería si Java lo usara antes de que C # lo hiciera). También Flex lo usa, y así sucesivamente. Sin embargo, la colocación de una I al principio del nombre suena a notación húngara y por eso me incomoda usarla.
Entonces, la pregunta es, ¿hay alguna manera alternativa de indicar que Algo es una interfaz, en lugar de una clase y hay alguna necesidad de denotarlo así de todos modos? ¿O es un caso que se convierta en un estándar y entonces debería aceptarlo y dejar de tratar de provocar "guerras religiosas" sugiriendo que se haga de otra manera?
Del libro de Directrices 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, de las anotaciones sobre el nombre de la interfaz:
KRZYSZTOF CWALINA: Uno de los pocos prefijos utilizados es "I" para las interfaces (como en ICollection), pero eso es por razones históricas. En retrospectiva, creo que hubiera sido mejor usar nombres de tipos regulares. En la mayoría de los casos, a los desarrolladores no les importa que algo sea una interfaz y no una clase abstracta, por ejemplo.
BRAD ABRAMS: Por otro lado, el prefijo "I" en las interfaces es un claro reconocimiento de la influencia de COM (y Java) en .NET Framework. COM popularizó, incluso institucionalizó, la notación de que las interfaces comienzan con "I." Aunque discutimos sobre la divergencia de este patrón histórico, decidimos llevar adelante el patrón ya que muchos de nuestros usuarios ya estaban familiarizados con COM.
JEFFREY RICHTER: Personalmente, me gusta el prefijo "I" y me gustaría tener más cosas como esta. Los pequeños prefijos de un carácter hacen mucho para mantener el código escueto y, a la vez, descriptivo. Como dije antes, uso prefijos para mis campos de tipo privado porque me parece muy útil.
BRENT RECTOR Nota: esta es realmente otra aplicación de la notación húngara (aunque una sin las desventajas del uso de la notación en nombres de variables).
Se ha convertido en una norma ampliamente adoptada, y si bien es una forma de húngaro, como afirma Brent, no adolece de las desventajas de utilizar la notación húngara en los nombres de variables.
El estándar de codificación para Symbian tiene interfaces (clases de C ++ abstractas puras) indicadas con una M en lugar de una I.
De lo contrario, la única otra forma que he visto de indicar interfaces es a través del contexto.
Para .NET, el libro de Directrices 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 añadir que no me gusta la notación húngara también, pero este y el caso de las variables de clase prefijadas con un guión bajo son buenas excepciones para mí, porque hacen que el código sea mucho más legible.
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 abuso de la misma) pero creo que da el valor suficiente como para merecer la pena 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 para hacerlos fácilmente distinguibles solo con el prefijo I.
Un pequeño punto de datos: trabajo con Java y con C # una cantidad justa, y regularmente me encuentro teniendo que verificar qué tipos en Java son realmente interfaces, particularmente alrededor del marco de recopilación. .NET simplemente hace esto simple. Tal vez no molesta a otras personas, pero me molesta.
+1 por IFoo de mi parte
Se trata de estilo y legibilidad . La prefijación 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 propios compiladores no les puede importar menos.
Siempre he pensado que esta convención de nombres es un poco de dinosaurio. Hoy en día, los IDEs son lo suficientemente poderosos como para decirnos que algo es una interfaz. Agregando que hago que el código sea más difícil de leer, así que si realmente quieres tener una convención de nomenclatura que separe las interfaces de las clases, anexaría Impl al nombre de la clase implementadora.
public class CustomerImpl implements Customer
Usted pidió una alternativa, así que aquí hay una que he encontrado:
No use prefijos en la clase de interfaz, pero use un 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 el tipo de hormigón generalmente menos utilizado?
Este enfoque introduce una incoherencia en que algunos tipos concretos serán prefijados (los que tienen interfaces que coinciden) y otros no. Esto puede ser útil, ya que recuerda a los desarrolladores que existe una interfaz y que su uso debe preferirse al tipo concreto.
Para ser sincero, uso el prefijo en la interfaz, pero creo que es más porque me he acostumbrado y me siento cómodo con él.
Como programador de .NET (en su mayor parte), en realidad prefiero la convención de Java de dejar el I
aquí, por una razón simple: 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 gran cantidad de refactorización innecesaria.
Por otro lado, el uso del cliente debe ser transparente, por lo que no deberían preocuparse por este tipo de pista. Además, el sufijo "capaz" en "Thingable" debería ser suficiente como una pista. Funciona bastante bien en Java.
/ EDITAR: Me gustaría señalar que el razonamiento anterior me llevó a soltar el prefijo I
para proyectos privados. Sin embargo, al verificar uno de ellos contra el conjunto de reglas de FxCop, volví rápidamente al uso de I
La consistencia gana aquí, a pesar de que una consistencia tonta es el duende de las mentes pequeñas .
Mi principal suposición es que lo más importante es mantener la legibilidad en el dominio como parte de la implementación. Por lo tanto:
Si tiene un comportamiento y una posible implementación, simplemente no cree una interfaz:
clase pública AnswerGenerator {}
Si tiene un comportamiento y muchas implementaciones posibles, entonces no hay problema y puede soltar la "I" y tener:
interfaz pública AnswerGenerator {}
clase pública StupidAnswerGenerator: AnswerGenerator {}
clase pública RandomAnswerGenerator: AnswerGenerator {}
clase pública GoogleSearchAnswerGenerator: AnswerGenerator {}
// ...
El verdadero problema surge cuando tiene un comportamiento y una posible implementación, pero necesita una interfaz para describir su comportamiento (por ejemplo, para realizar pruebas convenientes, debido a la convención en su proyecto, al uso de alguna biblioteca / marco que haga cumplir esto, ...). Las posibles soluciones, otras por el prefijo de la interfaz son:
a) Prefijo o sufijo 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 AnswerMachine.Interfaces {interfaz pública AnswerGenerator {}}
espacio de nombres AnswerMachine {public class AnswerGenerator: Interfaces.AnswerGenerator {}}
c) Use un espacio de nombres diferente para la implementación:
espacio de nombres AnswerMachine {public interface AnswerGenerator {}}
espacio de nombres AnswerMachine.Implementations {public class AnswerGenerator: AnswerMachine.AnswerGenerator {}}
Actualmente estoy experimentando con la última posibilidad. Tenga en cuenta que en el archivo fuente de implementación aún puede tener "using AnswerMachine;" y tiene un acceso conveniente a los objetos de dominio.
ACTUALIZACIÓN: A pesar de que todavía creo que la última posibilidad es la más limpia, su único inconveniente es que a pesar de "usar AnswerMachine"; le da acceso a todos los objetos de dominio, debe poner como prefijo todas las interfaces de dominio para que no se confundan con sus implementaciones. Puede parecer algo no muy conveniente, pero en el diseño limpio, por lo general, una clase no utiliza muchos otros objetos de dominio y, en general, solo debe usar el prefijo en la declaración de campo y en 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 un problema serio en tal proyecto, porque tiene lógica de dominio y preocupaciones de infraestructura mezcladas en la misma capa de abstracción. Por lo tanto, recomiendo soluciones " a " o " c ".