las - interfaces en java pdf
Nombre de la interfaz en Java (11)
La mayoría de los lenguajes OO prefijan sus nombres de interfaz con una I mayúscula, ¿por qué Java no hace esto? ¿Cuál fue la razón para no seguir esta convención?
Para demostrar lo que quiero decir, si quisiera tener una interfaz de usuario y una implementación de usuario, tendría dos opciones en Java:
- Clase = Usuario, Interfaz = Interfaz de usuario
- Class = UserImpl, Interface = User
Donde en la mayoría de los idiomas:
Clase = Usuario, Interfaz = IUser
Ahora, podría argumentar que siempre podría elegir el nombre más descriptivo para la implementación del usuario y el problema desaparece, pero Java está impulsando un enfoque de POJO a las cosas y la mayoría de los contenedores IOC usan DynamicProxies ampliamente. Estas dos cosas juntas significan que tendrá muchas interfaces con una sola implementación de POJO.
Entonces, supongo que mi pregunta se reduce a: "¿Vale la pena seguir la convención más amplia de nomenclatura de interfaces, especialmente a la luz de hacia dónde se dirigen los marcos de Java?"
¿Es esta una convención de nombramiento más amplia en algún sentido real? Estoy más en el lado de C ++, y no estoy realmente en Java y descendientes. ¿Cuántas comunidades lingüísticas utilizan la I convención?
Si tiene una convención de nomenclatura estándar de tienda independiente del idioma aquí, úsela. Si no, vaya con la convención de nomenclatura de idioma.
¿Existe realmente una diferencia entre:
class User implements IUser
y
class UserImpl implements User
Si todo lo que estamos hablando es nombrar convenciones?
Personalmente, prefiero NO preceder a la interfaz con I
ya que quiero estar codificando a la interfaz y considero que eso es más importante en términos de la convención de nomenclatura. Si llama a la interfaz IUser
, todos los consumidores de esa clase deben saber que es un IUser
. Si llama a la clase UserImpl
, solo la clase y su contenedor DI conocen la parte Impl
y los consumidores solo saben que están trabajando con un User
.
Por otra parte, los tiempos en los que me he visto obligado a usar Impl
porque no se presenta un nombre mejor han sido pocos porque la implementación se nombra de acuerdo con la implementación porque ahí es donde es importante, por ejemplo
class DbBasedAccountDAO implements AccountDAO
class InMemoryAccountDAO implements AccountDAO
= v = El prefijo "I" también se usa en el marco de Wicket, donde me acostumbré rápidamente. En general, doy la bienvenida a cualquier convención que acorte los voluminosos nombres de clase de Java. Sin embargo, es una molestia que todo esté ordenado alfabéticamente bajo "I" en los directorios y en el Javadoc.
La práctica de codificación Wicket es similar a Swing, ya que muchas instancias de control / widget se construyen como clases internas anónimas con declaraciones de métodos en línea. Molestamente, se diferencia 180 ° de Swing en que Swing usa un prefijo ("J") para las clases implementadoras.
El sufijo "Impl" es una abreviatura elegante y no se internacionaliza bien. Si al menos hubiésemos ido con "Imp" sería más lindo (y más corto). "Impl" se usa para IOC, especialmente para Spring, por lo que estamos atascados con eso por ahora. Sin embargo, se vuelve un poco esquizo siguiendo 3 convenciones diferentes en tres partes diferentes de una base de código.
Bob Lee dijo una vez en una presentación:
¿Cuál es el punto de una interfaz si solo tiene una implementación?
Entonces, empiezas con una implementación, es decir, sin una interfaz. más adelante usted decide, bueno, hay una necesidad de una interfaz aquí, por lo que convierte su clase en una interfaz.
entonces se vuelve obvio: su clase original fue llamada Usuario. su interfaz ahora se llama usuario. tal vez usted tiene un UserProdImpl y un UserTestImpl. Si diseñó bien su aplicación, todas las clases (excepto las que crean una instancia del Usuario) no se modificarán y no notarán que de repente se les pasa una interfaz.
para que quede claro -> Interfaz de usuario Implementación UserImpl.
Como dijo otro póster, normalmente es preferible que las interfaces definan capacidades y no tipos. No tendería a "implementar" algo como un "Usuario", y es por eso que "IUser" a menudo no es realmente necesario en la forma descrita aquí. A menudo veo clases como sustantivos e interfaces como adjetivos:
class Number implements Comparable{...}
class MyThread implements Runnable{...}
class SessionData implements Serializable{....}
A veces, un Adjetivo no tiene sentido, pero en general todavía estaría usando interfaces para modelar comportamientos, acciones, capacidades, propiedades, etc., no tipos.
Además, si realmente solo ibas a hacer un usuario y llamarlo Usuario, ¿para qué sirve tener una interfaz IUser? Y si va a tener algunos tipos diferentes de usuarios que necesitan implementar una interfaz común, ¿qué le permite agregar una "I" a la interfaz al elegir los nombres de las implementaciones?
Creo que un ejemplo más realista sería que algunos tipos de usuarios necesitan poder iniciar sesión en una API en particular. Podríamos definir una interfaz de inicio de sesión, y luego tener una clase principal de "Usuario" con SuperUser, DefaultUser, AdminUser, AdministrativeContact, etc. suclasses, algunas de las cuales implementarán o no la interfaz de inicio de sesión (¿Se puede iniciar sesión?) Según sea necesario.
En C # es
public class AdminForumUser : UserBase, IUser
Java diría
public class AdminForumUser extends User implements ForumUserInterface
Debido a eso, no creo que las convenciones sean tan importantes en java para las interfaces, ya que existe una diferencia explícita entre la herencia y la implementación de la interfaz. Yo diría que simplemente elija cualquier convención de nomenclatura que desee, siempre y cuando sea consistente y use algo para mostrar a las personas que estas son interfaces. No he hecho Java en unos pocos años, pero todas las interfaces estarían en su propio directorio, y esa era la convención. Realmente nunca tuve problemas con eso.
En mi experiencia, la convención "I" se aplica a las interfaces que están destinadas a proporcionar un contrato a una clase, particularmente cuando la interfaz en sí no es una noción abstracta de la clase.
Por ejemplo, en su caso, solo esperaría ver IUser
si el único usuario que pretende tener es User
. Si planea tener diferentes tipos de usuarios ( NoviceUser
, ExpertUser
, etc.) esperaría ver una interfaz de User
(y, quizás, una clase de AbstractUser
que implemente alguna funcionalidad común, como get/setName()
).
También esperaría que las interfaces que definen capacidades ( Comparable
, Iterable
, etc.) se IIterable
así, y no como IComparable
o IIterable
.
Prefiero no usar un prefijo en las interfaces:
El prefijo duele legibilidad.
El uso de interfaces en los clientes es la mejor manera estándar de programar, por lo que los nombres de las interfaces deben ser lo más cortos y agradables posible. Implementar clases debería ser más feo para desalentar su uso.
Cuando se cambia de una clase abstracta a una interfaz, una convención de codificación con el prefijo I implica cambiar el nombre de todas las apariciones de la clase, ¡no es bueno!
Puede haber varias razones por las que Java generalmente no usa la convención IUser.
Parte del enfoque orientado a objetos es que no debe saber si el cliente está utilizando una interfaz o una clase de implementación. Por lo tanto, incluso List es una interfaz y String es una clase real, se puede pasar un método a ambos, no tiene sentido distinguir visualmente las interfaces.
En general, en realidad preferiremos el uso de interfaces en el código del cliente (preferimos Listar a ArrayList, por ejemplo). Por lo tanto, no tiene sentido hacer que las interfaces se destaquen como excepciones.
La convención de nomenclatura de Java prefiere nombres más largos con significados reales a prefijos de estilo húngaro. De modo que el código será lo más legible posible: una Lista representa una lista y un Usuario representa un usuario, no un IUser.
Siguiendo buenos principios de OO, su código debería (en la medida de lo posible / práctico) depender de abstracciones en lugar de clases concretas. Por ejemplo, generalmente es mejor escribir un método como este:
public void doSomething(Collection someStuff) {
...
}
que esto:
public void doSomething(Vector someStuff) {
...
}
Si sigue esta idea, mantengo que su código será más legible si le asigna nombres de interfaces como "Usuario" y "Cuenta bancaria" (por ejemplo), en lugar de "IUser", "UserInterface" u otras variaciones.
Los únicos bits de código que deberían preocuparse por las clases concretas reales son los lugares donde se construyen las clases concretas. Todo lo demás debe escribirse usando las interfaces.
Si hace esto, entonces los nombres de clase concretos "feos" como "UserImpl" deben ocultarse de manera segura del resto del código, que puede continuar utilizando los nombres de interfaz "nice".
También hay otra convención, utilizada por muchos proyectos de código abierto, incluyendo Spring.
interface User {
}
class DefaultUser implements User {
}
class AnotherClassOfUser implements User {
}
Personalmente no me gusta el prefijo "I" por la sencilla razón de que es una convención opcional. Entonces, si adopto esto, ¿significa IIOPConnection una interfaz para IOPConnection? ¿Qué pasa si la clase no tiene el prefijo "I"? ¿Entonces sé que no es una interfaz? La respuesta aquí es no, porque no siempre se siguen las convenciones, y su vigilancia creará más trabajo que la convención misma salve.