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

Resuelto Amir Rachum asked hace 14 años • 9 respuestas

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

Cuando esto sucede, normalmente nombro la interfaz con el nombre "normal", como Trucky nombro la clase real TruckClass.

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

Amir Rachum avatar May 12 '10 05:05 Amir Rachum
Aceptado

Nombra tu Interfacelo que es. Truck. No ITruckporque no sea un, ITruckes un Truck.

Un Interfaceen Java es un Type . Entonces tienes DumpTruck, TransferTruck, WreckerTruck, , CementTrucketc.implements Truck

Cuando usas el Interfaceen lugar de una subclase, simplemente lo lanzas a Truck. Como en List<Truck>. Poner Ial frente es solo una tautología de notación de estilo húngaro de sistemas que no agrega nada más que más cosas para escribir en su código.

Todos los IDE de Java modernos marcan interfaces e implementaciones y todo eso sin esta notación tonta. No lo llames TruckClassasí como tautología tan mala como la IInterfacetautologí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 como AbstractTruck. Dado que solo las subclases verán esto y nunca debes transmitir a una Abstractclase, agrega cierta información de que la clase es abstracta y de cómo debe usarse. Aún se podría encontrar un nombre mejor que AbstractTruckusar BaseTrucko DefaultTrucken su lugar, ya que abstractestá en la definición. Pero dado que Abstractlas clases nunca deberían ser parte de ninguna interfaz pública, creo que es una excepción aceptable a la regla. Formar constructores protectedcontribuye en gran medida a superar esta división.

Y el Implsufijo también es más ruido. Más tautología. Todo lo que no sea una interfaz es una implementación, incluso las clases abstractas que son implementaciones parciales. ¿ Vas a poner ese Implsufijo tonto en cada nombre de cada clase ?

Es Interfaceun contrato sobre lo que los métodos y propiedades públicos deben soportar, también es información de tipo . Todo lo que implementa Truckes un Tipo de Truck.

Mire la propia biblioteca estándar de Java. Lo ves IList, ArrayListImpl, LinkedListImpl? No, ves Listy ArrayList, y LinkedList. Aquí hay un buen artículo sobre esta pregunta exacta. Cualquiera de estas tontas convenciones de nomenclatura de prefijos/sufijos también viola el principio DRY .

Además, si se encuentra agregando DTO, JDOu BEANotros sufijos tontos y repetitivos a objetos, entonces probablemente pertenezcan a un paquete en lugar de todos esos sufijos. Los espacios de nombres correctamente empaquetados se autodocumentan y reducen toda la información redundante e inútil en estos esquemas de nombres propietarios realmente mal concebidos que la mayoría de los lugares ni siquiera se adhieren internamente de manera consistente.

Si todo lo que se le ocurre para que su Classnombre sea único es agregarle el sufijo Impl, entonces debe reconsiderar la Interfaceposibilidad de tener un. Entonces, cuando se encuentra en una situación en la que tiene un Interfacey uno Implementationque no está exclusivamente especializado, Interfaceprobablemente no lo necesite Interfaceen la mayoría de los casos.

Sin embargo, en general por razones de mantenimiento, capacidad de prueba y burla, es una buena práctica proporcionar interfaces. Consulte esta respuesta para obtener más detalles .

Consulte también este interesante artículo de Martin Fowler sobre este tema de InterfaceImplementationPair

 avatar May 11 '2010 22:05

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 de Dependencia/Inversión de Control (¡no nos llames, nosotros te llamaremos!).

Entonces, 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 simulada para pruebas y otra 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 puede mantenerse mediante una implementación simulada estricta para pruebas.

de hecho, puede establecer pruebas en las que los simulacros 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 el código de producción (sin verificar los argumentos que deberían no ser nulo por ser nulo ya que el simulacro arrojó excepciones en tus pruebas y sabes que los argumentos no son nulos debido a que se corrigió el 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 comprenda su potencial, querrá usarlo en todas partes y se encontrará creando interfaces todo el tiempo, incluso si solo habrá una ( producción real) implementación.

Para esta implementación (puede inferir, y estaría en lo cierto, que creo que los simulacros para las pruebas deberían llamarse Mock(InterfaceName)), prefiero el nombre Default(InterfaceName). Si aparece una implementación más específica, se le puede nombrar apropiadamente. Esto también evita el sufijo Impl que particularmente no me gusta (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 quieres que tu clase base sea instanciable más adelante, pero ahora estás atascado con el nombre "Abstract(InterfaceName)" , y esto te obliga a cambiar el nombre de la clase, lo que posiblemente cause una pequeña confusión, pero si siempre fue Base(InterfaceName), eliminar el modificador abstracto no cambia cuál era la clase.

MetroidFan2002 avatar May 12 '2010 00:05 MetroidFan2002

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

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

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

Bert F avatar May 11 '2010 22:05 Bert F

La convención estándar de C#, que también funciona bastante bien en Java, es anteponer a todas las interfaces un I- por lo que su interfaz de controlador de archivos será IFileHandlery su interfaz de camión será ITruck. Es consistente y facilita distinguir las interfaces de las clases.

tzaman avatar May 11 '2010 22:05 tzaman

Me gustan los nombres de interfaz que indican qué contrato describe una interfaz, como "Comparable" o "Serializable". Sustantivos como "Camión" en realidad no describen la condición de camión: ¿cuáles son las habilidades de un camión?

Respecto a las convenciones: he trabajado en proyectos donde cada interfaz comienza con una "I"; Si bien esto es algo ajeno a las convenciones de Java, facilita la búsqueda de interfaces. Aparte de eso, el sufijo "Impl" es un nombre predeterminado razonable.

mfx avatar May 11 '2010 22:05 mfx