Cómo implementar solo una parte de una interfaz

13

Al desarrollar en OOP, a veces una interfaz / contrato es dado por una biblioteca que no puede alterar. Llamemos a esta interfaz J.

Ahora tiene un objeto de clase A que consume objetos que implementan esta interfaz. En el interior A solo se necesita una pequeña parte de las definiciones de la interfaz. Algunas de las clases de objetos las he creado durante el proyecto (llamemos a una de ellas tipo D), por lo que hay una sobrecarga en la implementación de todo lo que está dentro de la interfaz J.

Quiero implementar un subconjunto de la funcionalidad en la interfaz J, pero hasta ahora mis soluciones no me satisfacen:

  • implementar todos los aspectos de J y luego lanzar "notImplementedExceptions" desinforma al usuario de mis objetos: parecería que mis objetos de tipo D cumplen con la interfaz J, pero no lo hacen, y otros consumidores de mis objetos (que aceptan los objetos que implementan la interfaz J) no pueden confiar en la integridad de mis objetos.
  • La implementación de una interfaz recién definida me impide utilizar objetos que implementen solo la interfaz J, aunque la interfaz J es totalmente compatible con mi propia interfaz.
  • Permitir que mis objetos personalizados implementen la interfaz J generaría una sobrecarga significativa, ya que no necesitan toda esta funcionalidad.

Cuando pude alterar la interfaz J, crearía una "super-interfaz" K que tenía este subconjunto de la funcionalidad de la interfaz J, y haría que la interfaz J se heredara de la interfaz K. Pero no puedo modificar la interfaz J.

¿Qué es una solución orientada a objetos para este problema? ¿La mejor solución sigue implementando "solo" la interfaz J? ¿O hay formas OOP de "superclase" una interfaz sin alterarla?

    
pregunta vstrien 01.06.2011 - 10:34

6 respuestas

8

si no controlas la interfaz J, estás bloqueado.

puede, para mayor claridad, implementar su propia interfaz subJ y interfaz J, y usar subJ en su propio código para dejar en claro que los métodos adicionales en la interfaz J no son necesarios, pero no No creo que realmente te gane mucho.

si es posible, implemente la interfaz completa J completamente

si es posible, comuníquese con el propietario de la interfaz J y pídale que lo modifique para que se adapte mejor a sus propósitos

    
respondido por el Steven A. Lowe 01.06.2011 - 11:14
25

El punto central de la implementación de una interfaz es proporcionar un contrato firme entre la persona que llama y la persona que llama que nunca cambia, mientras que los detalles de la implementación pueden variar.

Al implementar la interfaz J, le estás diciendo al mundo exterior lo que puedes hacer.

Si no necesita la mitad de lo que hace J, entonces la interfaz debería subdividirse, ya que no es tan pequeña como debería ser, o debe lanzar NotImplementedException sobre los métodos y propiedades que no necesita . Sin embargo, esta no es la mejor solución, ya que confunde las expectativas de las personas sobre lo que puede hacer su código.

    
respondido por el ChrisF 01.06.2011 - 11:18
4

Si su clase de consumidor A no requiere toda la interfaz J, sugeriría crear una nueva interfaz (llámela K), que describa de manera integral todo lo que requiere.

Esto proporciona una señal clara para cualquiera que use la clase A en cuanto a cuál es su lado del contrato. De este modo se mejoran las posibilidades de reutilización. Si alguien necesita proporcionar un objeto que implemente una interfaz grande y compleja, para hacer algo relativamente simple, es probable que terminen escribiendo lo que la clase A haga por sí mismos.

Para permitir que la clase A consuma objetos que solo implementan la interfaz J, puede proporcionar una clase envoltura que implemente la interfaz K y pase las llamadas apropiadas a un miembro de la interfaz J.

    
respondido por el Paul Butcher 01.06.2011 - 12:04
3

Aunque estoy de acuerdo con las respuestas existentes que dicen que realmente necesitas implementar J completamente (con excepciones para los métodos no implementados) o no, en absoluto, una posible solución es la siguiente:

  • Cree una interfaz K más pequeña que sea un subconjunto de J e implemente los métodos necesarios.
  • Cree un contenedor para A que acepte objetos que implementen J y K.
  • En el caso de un pase en J, simplemente empújalo a la instancia de A.
  • En el caso de un pase en K, ejemplifique una implementación anónima de J, cableando solo los métodos de K a J que están allí. Pase el resultado a la instancia de A.

Tenga en cuenta que esta es una solución bastante fea, ya que requiere un envoltorio que acepte varias cosas que son esencialmente lo mismo. Pero sí logra lo siguiente:

  • No hay cambios en J o A.
  • No hay implementaciones "expuestas" de J que estén incompletas.

Si su lenguaje OO no permite la creación de instancias anónimas de la interfaz, puede crear una implementación ficticia de la interfaz e instanciarla.

    
respondido por el Deckard 01.06.2011 - 11:27
1

¿Cuánto tiempo le tomaría implementar la interfaz completa?

Si le llevaría una cantidad de tiempo considerable, esto indica un problema de diseño, y le aconsejaría (como lo hizo Steven A.) que se ponga en contacto con el propietario y vea si se puede cambiar en el futuro.

¿Utiliza la interfaz en su propio código, independientemente de la biblioteca de la interfaz?

Como sugirió Steven A., puedes usar tu propia interfaz como te gustaría verla en tu propio código. Esto al menos mantiene limpio su código interno. También puede enviar esto al propietario como la interfaz que esperaría encontrar. Tal vez esté de acuerdo con usted, o tal vez pueda explicarle por qué no se debe dividir la interfaz.

¿Su implementación necesitaría alguna vez a los miembros no utilizados de la interfaz?

En caso de que pueda esperar que nunca se los llame, ya que "no son compatibles", prefiero usar la NotSupportedException . Esto da una clara indicación de que nunca admitirá esta interfaz, en lugar de no implementarla.

    
respondido por el Steven Jeuris 01.06.2011 - 11:49
0

Implemente lo que necesita y lance una excepción NoImplementedException a los demás.

Esto es una cuestión de uso. Si no usa la interfaz, o sabe que su código no la usará, entonces no invierta tiempo en esto, ya que no necesita invertir tiempo en el código redundante.

Trabaje para la tarea en cuestión y mantenga un buen seguimiento para que otros la sigan si desean usar la interfaz.

Muchas interfaces en Java no se implementan en su totalidad.

Este es el enfoque de Apache a las cosas: enlace

    
respondido por el Display Name 01.06.2011 - 11:14

Lea otras preguntas en las etiquetas