Estoy escribiendo un juego en Typecript, y decidí al entrar que iba a tratar de adherirme a la idea de " programación basada en interfaz ", donde escribes código basado en una interfaz, en lugar de la implementación, de un objeto.
Escribí una buena cantidad de interfaces y clases que las implementan, luego di un paso atrás y me di cuenta de que las clases eran lo suficientemente simples como para que nunca necesite cambiar la implementación, ya que en realidad solo hay una forma de hacer lo que clase hace (mover una Phaser.Sprite
de forma restringida para actuar como un tanque).
Entonces recuerdo haber leído hace unos años sobre la idea de YAGNI , que básicamente es que no debes manipular excesivamente tu código para incluir cosas que quizás nunca uses.
Siguiendo las mejores prácticas, ¿debería cada clase implementar una interfaz, o debería limitarla a clases que espera que se intercambien en el futuro?
fuente
Respuestas:
La razón para tener interfaces es porque simplifica el polimorfismo. Lo que significa que puede enviar instancias por contrato en lugar de conocer su implementación real. Por ejemplo, puede enviar un "Lector" a un método, de modo que dicho método llamado pueda usar su método "read ()". Al declarar una interfaz "Lector", puede hacer que cualquier objeto se ajuste a este contrato, implementando los métodos que especifica. De esta manera, cualquier persona que llama puede asumir que existirán ciertos métodos, incluso si los objetos subyacentes al contrato pueden ser completamente diferentes.
Esto desacopla el polimorfismo de una clase base y lo hace posible también entre las fronteras de la cadena de clase, al implicar un contrato.
Ahora ... Esto solo es útil si tiene la necesidad de que múltiples cadenas de herencia actúen de la misma manera, o si tendrá muchas clases base con comportamiento común que querrá transmitir a otros usuarios.
Si solo tiene UNA cadena de herencia (clase base-> subclase) o solo la base, o no tiene necesidad de PASAR los objetos relacionados a otra persona o usarlos genéricamente, entonces no agregaría implementaciones de interfaz, ya que esa noción es entonces inútil.
fuente
Moves
yShoots
para su ejemplo de tanque) para una sola clase.Si no está seguro de si realmente necesita las interfaces, entonces probablemente no. Este es el núcleo del principio YAGNI. Cuando necesita poder intercambiar la implementación, entonces introduce una interfaz.
fuente
Crear una interfaz para cada clase es un poco exagerado. Desde una perspectiva puramente orientada a objetos, cada clase ya tiene una interfaz . Una interfaz no es más que los métodos públicos y los miembros de datos de una clase.
Normalmente usamos "interfaz" para referirnos a "una clase Java definida usando la
interface
palabra clave" o "una clase C ++ con solo funciones virtuales públicas y puras". Estas son abstracciones útiles, porque desacoplan la interfaz de una clase de su implementación.Con eso en mente, use interfaces cuando sea apropiado.
¿Habrá múltiples implementaciones para una interfaz? Si es así, esta situación puede ser un candidato para extraer métodos comunes de cara al público en una interfaz.
¿Transmitiré implementaciones de una interfaz potencial a otros módulos que no deberían conocer el funcionamiento interno de mi módulo? Una interfaz puede ser útil aquí, porque reduce el tamaño del punto de contacto entre los módulos.
Observe las palabras de comadreja de arriba: "puede" ser un candidato, "puede ser" útil. No existe una regla estricta que diga "sí" o "no" para una situación dada.
Dicho esto, lo más probable es que tener una interfaz para todo sea excesivo. Si ves este patrón, llegarás lejos:
fuente
interface
, da la casualidad de que todo en Javainterface
también es su interfaz pública (concepto OO).Puede ser muy tentador para los nuevos desarrolladores pensar en las interfaces como un inconveniente que simplemente agregas solo porque te dicen que es la "mejor práctica". Si está haciendo esto a ciegas, huele a programación de culto de carga .
Hay una serie de muy buenas razones por las que debería considerar las interfaces para desarrollos más grandes en lugar de agrupar un conjunto de clases.
Marcos burlones
Si desea probar una aplicación de varias capas sin tener que crear objetos para las diversas capas, sin duda querrá usar marcos de imitación para simular las capas. Las interfaces se usan ampliamente aquí.
Inyección de dependencia
Si bien han caído en desgracia debido a la hinchazón que agregan, la idea es sólida: la capacidad de intercambiar concreciones simplemente en función de una interfaz. El principio también se puede encontrar en muchos patrones de diseño, como el patrón de fábrica.
Estos enfoques se resumen en la D de principios SÓLIDOS . El problema de esto es: use abstracciones, no concreciones.
Al igual que los patrones de diseño en sí, cuándo usarlos es una decisión decisiva. El punto clave es entender cómo las interfaces son útiles, no solo pegarlas en tus clases porque sientes que tienes que hacerlo. Hay una buena discusión de los diversos méritos de DIP y YAGNI aquí .
fuente