OOP: ¿Cuáles son algunas de las situaciones en las que el diseño basado en clase es mejor que el basado en interfaz?


9

Estaba leyendo el sitio web de JDOM .

¿Por qué la API JDOM se define en términos de clases concretas en lugar de interfaces?

Jason Hunter resume los argumentos en contra de una API basada en interfaz para JDOM:

Con las interfaces, todo se convierte en una fábrica, los elementos tienen que 'importarse' en nuevos documentos en lugar de simplemente agregarse, las características como la serialización a largo plazo no pueden garantizarse, y la lista continúa.

Empezamos con interfaces en realidad. Durante nuestra revisión previa al lanzamiento a algunos compañeros, recibimos la retroalimentación de que deberíamos probar clases concretas. Lo hicimos, y el diseño fue mucho mejor para eso.

Soy un diseñador principiante. Todos los consejos que he escuchado hasta ahora son consejos contra el uso del diseño con clases concretas.

Puede estar usando clases concretas que son apropiadas en ciertos lugares. ¿Hay algún problema de clase común para el que está bien usar clases concretas en el diseño?



También puede consultar la serie "Limite sus abstracciones": ayende.com/blog/153889/…
henginy

"Lo hicimos, y el diseño fue mucho mejor para eso". - ¿Cómo fue mejor?
CodeART

Respuestas:


5
  • La herencia crea dependencias en la implementación , lo que podría ser un gran problema con respecto a la mantenibilidad. El corolario de esto es que puede utilizar de forma segura la herencia y las clases concretas cuando se trata de objetos de transferencia de datos , que por definición casi no contienen implementación. También puede usar la herencia de clases concretas cuando desee esta dependencia. Es posible que desee utilizar una clase abstracta que contenga los métodos comunes (generalmente funciones de utilidad) en la parte superior de la jerarquía en esta situación.
  • Cuando utilice una jerarquía de clases concreta, no olvide aplicar el Principio de sustitución de Liskov .
  • No hay ningún problema con el uso de clases concretas para clientes (es decir, clases que usan, no clases que se usan).
  • En mi humilde opinión, puede utilizar clases concretas hasta que haya cosas que cambiar. El Principio Abierto / Cerrado le indicaría que use interfaces para evitar el acoplamiento, pero con respecto al Principio No lo necesitará , podría considerar usar clases concretas hasta el momento en que necesite cambiar algo en la implementación. El problema es que tendrías que cambiar a cada cliente de tus clases la primera vez que algo cambia en alguna parte. Si bien solo tiene una herramienta posible para hacer algo, puede usar clases concretas IMO.

[EDITAR] El sitio web de JDOM toma java.io.File como ejemplo, pero este es definitivamente un diseño basado en la interfaz, ya que uno puede manipular una instancia de java.io.File como si fuera solo un serializable. En esta situación, solo los "creadores" conocerían la clase concreta


Hay dos definiciones conflictivas de "objeto de valor" flotando. La suya parece ser la menos común, también conocida como "objeto de transferencia de datos".
Michael Borgwardt

@MichaelBorgwardt Thx por señalar esto, ya que no quise decir solo "objeto de transferencia de datos": edito mi respuesta
Matthias Jouan,

1
El LSP es importante para cualquier relación de subtipo, implementación de interfaz y herencia.

2

Desde el sitio JDOM:

Jason (Hunter) fundó el proyecto JDOM a principios de 2000 junto con Brett McLaughlin

Es decir, cuando se introdujo Java 1.3. No había nada de madurez en lo que respecta al desarrollo de Java: los desarrolladores más experimentados solo tenían 4 años usando Java en el mejor de los casos. No había contenedores de IoC ampliamente utilizados, ni Hibernate. Apache Struts apenas estaba comenzando.

Lo cual es todo para decir que Jason y Brett estaban equivocados. Mucha gente todavía no lo "entendió". Si tenían fondos de C ++, bueno, no necesitabas interfaces en C ++ (bueno, estaban allí en C ++, pero realmente no los necesitabas, ¿verdad?), ¿Por qué demonios los usaban en Java? Bueno, hay muchas buenas razones, a las que otros pueden dirigirte.

Definitivamente estaban equivocados sobre

todo lo que se puede hacer con interfaces se puede hacer con subclases

Java no permite la herencia múltiple de clases, pero sí permite la implementación de múltiples interfaces. Eso puede hacer una verdadera diferencia.


2

Recuerde, primero, que en el desarrollo de software hay varias formas de resolver un problema, y ​​si algún desarrollador utiliza una técnica diferente a la suya, eso no significa que esté mal.

Uno de esos casos es "interfaces" versus (base) "clases". Hay situaciones en las que se puede lograr el mismo objetivo con ambas técnicas.

Para hacer las cosas más complicadas, hay varios usos de las interfaces, solo por mencionar:

  • uno es diseñar un "contrato" o "especificación" sin "implementación"
  • otro para agregar funcionalidad a una clase existente o jerarquía de clases
  • complementario al anterior, para permitir el acceso compartido entre diferentes objetos, tecnologías, por ejemplo: Enterprise Beans, CORBA, COM, WebServices
  • para emular herencia múltiple

Su pregunta se aplica al primer punto.

Cuando desee desarrollar una jerarquía de clases, no solo una sola clase, y varias clases están destinadas a compartir algunas características específicas, es posible que desee comenzar con una clase base, incluso si se puede hacer con una interfaz.

Y, deje las interfaces para los otros escenarios.

Un buen ejemplo son las bibliotecas de widgets (controles).

Sugiero que eche un vistazo a otros lenguajes de programación cómo usan las interfaces y clases como: PHP, Delphi (Object Pascal), C #.

Salud.


0

En general, desea una interfaz para todo lo que se pasa como parámetro o se devuelve, esencialmente para poder desacoplar la clase de sus dependencias.

Entonces, si estamos buscando una clase, nunca pasamos por alto, normalmente se me ocurren excepciones. No soy un desarrollador de Java, pero ciertamente en otros lenguajes similares no creo que haya visto interfaces definidas para excepciones.


0

Las reglas de diseño de API son realmente una cosa específica. No estoy seguro de que deba concluir nada de esas preguntas frecuentes en términos de cómo debe diseñar su código del día a día.

Para su código regular, aún es cierto que usará la interfaz o la herencia de clase abstracta con mucha más frecuencia que la herencia de vainilla IMO.

Para obtener una buena comprensión de esa regla, debe ubicarse no desde el punto de vista de una clase derivada frente a su superclase, sino desde el punto de vista de un objeto que depende de otro objeto. Casi siempre es mejor depender de una abstracción en lugar de una implementación concreta porque le permite aceptar una serie completa de clases diferentes como dependencias, dependiendo de su contrato y no de los detalles de su implementación.

El primer uso de esto es a menudo en las pruebas de unidad - si realmente quiere unidad de prueba de su clase en completo aislamiento, lo hace contra implementaciones falsas de sus dependencias que son diferentes de las implementaciones reales que serán utilizados en la producción.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.