Interfaces Java / Convención de nomenclatura de implementación [duplicar]


Esta pregunta ya tiene una respuesta aquí:

¿Cómo nombra las diferentes clases / interfaces que crea? A veces no tengo información de implementación para agregar al nombre de la implementación, como interfaz FileHandler y clase SqlFileHandler.

Cuando esto sucede generalmente nombro la interfaz en el nombre "normal", como Truck y nombre la clase real TruckClass.

¿Cómo se nombran las interfaces y las clases en este sentido?

Author: Joshua Taylor, 2010-05-12

9 answers

Nombra tu Interface lo que es. Truck. No ITruck porque no es un ITruck es a Truck.

Un Interface en Java es un Tipo. Entonces usted tiene DumpTruck, TransferTruck, WreckerTruck, CementTruck, etc que implement Truck.

Cuando estás usando el Interface en lugar de una subclase, simplemente lo lanzas a Truck. Como en List<Truck>. Poner I al frente es simplemente Estilo húngaro notación tautología que añade nada más que más cosas para escribir a su código.

Todos los IDE modernos de Java marque Interfaces e Implementaciones y lo que no sin esta notación tonta. No lo llames TruckClass que es tautología tan mala como la IInterface tautología.

Si es una implementación es una clase. La única excepción real a esta regla, y siempre hay excepciones, podría ser algo así como AbstractTruck. Dado que solo las subclases verán esto y nunca debes enviar a una clase Abstract, agrega cierta información de que la clase es abstracta y cómo debe ser utilizar. Todavía podría encontrar un nombre mejor que AbstractTruck y usar BaseTruck o DefaultTruck en su lugar, ya que abstract está en la definición. Pero dado que Abstract las clases nunca deben ser parte de ninguna interfaz pública, creo que es una excepción aceptable a la regla. Hacer los constructores protected va un largo camino para cruzar esta división.

Y el sufijo Impl es simplemente más ruido también. Más tautología. Cualquier cosa que no sea una interfaz es una implementación, incluso clases abstractas que son implementaciones parciales. Vas a poner ese tonto Impl sufijo en cada nombre de cada Class?

El Interface es un contrato sobre lo que los métodos y propiedades públicas tienen que soportar, también es Tipo información también. Todo lo que implementa Truckes un Tipo de Truck.

Busque en la propia biblioteca estándar de Java. ¿Ves IList, ArrayListImpl, LinkedListImpl? No, ves List y ArrayList, y LinkedList. Aquí está un buen artículo sobre esta pregunta exacta. Cualquiera de estas tontas convenciones de nomenclatura de prefijos/sufijos violan también el principio DRY.

También, si te encuentras añadiendo DTO, JDO, BEAN u otros sufijos repetitivos tontos a los objetos, entonces probablemente pertenezcan a un paquete en lugar de todos esos sufijos. Los espacios de nombres correctamente empaquetados se auto documentan y reducen toda la información redundante inútil en estos esquemas de nombres propietarios realmente mal concebidos que la mayoría los lugares ni siquiera se adhieren internamente de una manera consistente.

Si todo lo que se te ocurre para hacer que tu nombre Class sea único es sufijarlo con Impl, entonces necesitas replantearte tener un Interface. Así que cuando tienes una situación en la que tienes un Interface y un único Implementation que no está únicamente especializado de Interface probablemente no necesitas el Interface.

 762
Author: feeling abused and harassed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-04 17:36:02

He visto respuestas aquí que sugieren que si solo tiene una implementación, entonces no necesita una interfaz. Esto va en contra del principio de Inyección/Inversión de Control de Dependencia (no nos llame, le llamaremos!).

Así que sí, hay situaciones en las que desea simplificar su código y hacerlo fácilmente comprobable confiando en implementaciones de interfaz inyectadas (que también pueden ser proxy - su código no lo sabe!). Incluso si solo tiene dos implementaciones: una un simulacro para pruebas, y uno que se inyecta en el código de producción real-esto no hace que tener una interfaz sea superfluo. Una interfaz bien documentada establece un contrato,que también se puede mantener mediante una implementación de prueba estricta.

De hecho, puede establecer pruebas que tengan simks implementen el contrato de interfaz más estricto (lanzando excepciones para argumentos que no deberían ser nulos, etc.) y detectar errores en las pruebas, utilizando una implementación más eficiente en código de producción (no comprobar argumentos que no deberían ser null por ser null ya que el simulacro arrojó excepciones en sus pruebas y usted sabe que los argumentos no son null debido a la fijación del código después de estas pruebas, por ejemplo).

La inyección de dependencia / IOC puede ser difícil de entender para un recién llegado, pero una vez que entienda su potencial, querrá usarlo en todo el lugar y se encontrará haciendo interfaces todo el tiempo, incluso si solo habrá una (producción real) aplicación.

Para esta implementación (puede inferir, y estaría en lo correcto, que creo que las burlas para las pruebas deberían llamarse Mock(InterfaceName)), prefiero el nombre Default(InterfaceName). Si se presenta una implementación más específica, se puede nombrar apropiadamente. Esto también evita el sufijo Impl que particularmente me disgusta (si no es una clase abstracta, POR SUPUESTO que es un "impl"!).

También prefiero "Base (InterfaceName)" en lugar de "Abstract (InterfaceName) "porque hay algunas situaciones en las que desea que su clase base se convierta en instanciable más tarde, pero ahora está atascado con el nombre" Abstract(InterfaceName)", y esto lo obliga a cambiar el nombre de la clase, posiblemente causando una pequeña confusión, pero si siempre fue Base(InterfaceName), eliminar el modificador abstracto no cambia lo que era la clase.

 87
Author: MetroidFan2002,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-12 00:48:05

El nombre de la interfaz debe describir el concepto abstracto que representa la interfaz. Cualquier clase de implementación debe tener algún tipo de rasgos específicos que se puedan usar para darle un nombre más específico.

Si solo hay una clase de implementación y no se puede pensar en nada que la haga específica (implícita por querer nombrarla -Impl), entonces parece que no hay justificación para tener una interfaz en absoluto.

 57
Author: Michael Borgwardt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-11 22:27:12

Tiendo a seguir las pseudo-convenciones establecidas por Java Core / Sun, por ejemplo, en las clases de Colecciones:

  • List - interfaz para el objeto" conceptual "
  • ArrayList - implementación concreta de interface
  • LinkedList - implementación concreta de interface
  • AbstractList - implementación abstracta "parcial" para ayudar a las implementaciones personalizadas

Solía hacer lo mismo modelando mis clases de eventos según el paradigma AWT Event/Listener/Adapter.

 25
Author: Bert F,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-11 22:53:48

La convención estándar de C#, que también funciona bastante bien en Java, es prefijar todas las interfaces con un I - por lo que su interfaz de controlador de archivos será IFileHandler y su interfaz de camión será ITruck. Es consistente y hace que sea fácil distinguir las interfaces de las clases.

 18
Author: tzaman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-11 22:15:56

Me gustan los nombres de interfaz que indican qué contrato describe una interfaz, como "Comparable" o "Serializable". Los sustantivos como "Camión" realmente no describen el camión what ¿cuáles son las Habilidades de un camión?

Con respecto a las convenciones: He trabajado en proyectos donde cada interfaz comienza con una "I"; aunque esto es algo ajeno a las convenciones de Java, hace que encontrar interfaces sea muy fácil. Aparte de eso, el sufijo "Impl" es un nombre predeterminado razonable.

 18
Author: mfx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-12 09:55:35

A algunas personas no les gusta esto, y es más una convención. NET que Java, pero puede nombrar sus interfaces con un prefijo I mayúscula, por ejemplo:

IProductRepository - interface
ProductRepository, SqlProductRepository, etc. - implementations

Las personas que se oponen a esta convención de nomenclatura podrían argumentar que no debería importarle si está trabajando con una interfaz o un objeto en su código, pero me resulta más fácil de leer y entender sobre la marcha.

No nombraría la clase de implementación con un sufijo "Class". Eso puede llevar a confusión, porque usted puede en realidad trabaja con objetos" class " (es decir, Type) en su código, pero en su caso, no está trabajando con el objeto class, solo está trabajando con un objeto simple.

 7
Author: Andy White,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-11 22:16:45

TruckClass suena como si fuera una clase de Truck, creo que la solución recomendada es agregar Impl sufijo. En mi opinión, la mejor solución es contener dentro del nombre de la implementación alguna información, lo que está pasando en esa implementación en particular (como tenemos con List interfaz e implementaciones: ArrayList o LinkedList), pero a veces solo tiene una implementación y tiene que tener interfaz debido al uso remoto (por ejemplo), entonces (como se mencionó al principio) Impl es la solución.

 1
Author: Mirek Pluta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-11 22:27:50

Utilizo ambas convenciones:

Si la interfaz es una instancia específica de un patrón bien conocido (por ejemplo, Service, DAO), entonces puede que no necesite una "I" (por ejemplo, UserService, AuditService, UserDao) todo funciona bien sin la "I", porque el post-fix determina el patrón meta.

Pero, si tienes algo único o doble (normalmente para un patrón de devolución de llamada), entonces ayuda a distinguirlo de una clase (por ejemplo, IAsynchCallbackHandler, IUpdateListener, IComputeDrone). Estos son especiales interfaces de propósito diseñadas para uso interno, ocasionalmente la IInterface llama la atención sobre el hecho de que un operando es en realidad una interfaz, por lo que a primera vista es inmediatamente claro.

En otros casos se puede usar la I para evitar colisionar con otras clases concretas comúnmente conocidas (ISubject, IPrincipal vs Subject o Principal).

 1
Author: Justin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-11 23:29:28