Al desarrollar en OOP, a veces una biblioteca / interfaz proporciona una interfaz / contrato que no puede modificar. Llamemos a esta interfaz J.
Ahora tiene un objeto de clase A que consume objetos que implementan esta interfaz. Dentro de A solo se necesita una pequeña parte de las definiciones de la interfaz. Creé algunas de las clases de objetos durante el proyecto (llamemos a una de ellas tipo D), por lo que hay una sobrecarga en la implementación de todo dentro de la interfaz J.
Quiero implementar un subconjunto de la funcionalidad en la interfaz J, pero mis soluciones hasta ahora no me satisfacen:
- implementar todos los aspectos de J y luego arrojar "notImplementedExceptions" desinforma al usuario de mis objetos: parecería que mis objetos de tipo D se ajustan a la interfaz J, pero no lo hacen, y otros consumidores de mis objetos (que aceptan objetos que implementan la interfaz J) no puedo confiar en la integridad de mis objetos.
- Implementar una interfaz recién definida me prohíbe usar objetos que implementen solo la interfaz J, aunque la interfaz J es totalmente compatible con mi propia interfaz.
- Dejar que mis objetos personalizados implementen la interfaz J crearía una sobrecarga significativa, porque no necesitan toda esta funcionalidad.
Cuando podía alterar la interfaz J, creaba una "superinterfaz" K que tenía este subconjunto de la funcionalidad de la interfaz J, y hacía que la interfaz J heredara de la interfaz K. Pero no puedo alterar la interfaz J.
¿Cuál es una solución orientada a objetos para este problema? ¿La mejor solución sigue implementando la interfaz "justa" J? ¿O hay formas OOP de "superclasificar" una interfaz sin alterarla?
fuente
Respuestas:
si no controlas la interfaz J, estás atascado.
puede, para mayor claridad, implementar su propia interfaz subJ e 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 creo que eso realmente le gane mucho
si es posible, implemente toda la interfaz J completamente
si es posible, comuníquese con el propietario de la interfaz J y pídale que la modifique para adaptarla mejor a sus propósitos.
fuente
El objetivo de implementar 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 implementación pueden variar.
Al implementar la interfaz J, le está diciendo al mundo exterior lo que puede hacer.
Si no necesita la mitad de lo que hace J, entonces la interfaz realmente debería subdividirse, ya que no es tan pequeña como podría ser, o debe agregar
NotImplementedException
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.fuente
Si su clase de consumidor A no requiere toda la interfaz J, entonces sugeriría crear una nueva interfaz (llamada K), que describa exhaustivamente todo lo que sí requiere.
Esto proporciona una señal clara a 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 termine escribiendo lo que la clase A hace por sí mismo.
Para permitir que la clase A consuma objetos que implementan la interfaz J solo, puede proporcionar una clase de contenedor que implemente la interfaz K y transfiera las llamadas apropiadas a un miembro de la interfaz J.
fuente
Si bien estoy de acuerdo con las respuestas existentes que dicen que realmente necesita implementar J completamente (con excepciones para los métodos no implementados) o no aplicarlo, una posible solución es la siguiente:
Tenga en cuenta que esta es una solución bastante fea, ya que requiere un contenedor que acepta varias cosas que son esencialmente lo mismo. Pero logra lo siguiente:
Si su lenguaje OO no permite la creación de instancias de interfaz anónima, puede crear una implementación ficticia de la interfaz e instanciar eso.
fuente
¿Cuánto tiempo le llevaría implementar toda la interfaz?
Si le tomara una cantidad considerable de tiempo, esto indica un problema de diseño, y le aconsejaría (como lo hizo Steven A. antes que yo) que se comunique con el propietario y vea si se puede cambiar en el futuro.
¿Utiliza la interfaz en su propio código, independiente de la biblioteca de la interfaz?
Como Steven A. sugirió, puede usar su propia interfaz como le gustaría verla en su 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 él esté de acuerdo con usted, o tal vez pueda explicarle por qué la interfaz no debe dividirse.
¿Alguna vez su implementación necesitaría los miembros no utilizados de la interfaz?
En caso de que pueda esperar que nunca se les llame ya que 'no son compatibles', prefiero usar el
NotSupportedException
. Esto proporciona una indicación clara de que nunca admitirá esta interfaz, en lugar de que no la haya implementado.fuente
NotSupportedException
deja en claro que no es compatible con ese método.NotImplementedException
para el código de producción, donde de lo contrario escribiría "TODO: Implemente esto" Lamentablemente, no aparecen en la lista de tareas de Visual Studio . Pero en la práctica, apenas dejo un método sin implementar por más de dos días. Resharper también muestra esas excepciones en negrita (al menos con mi configuración). :)Implemente lo que necesita y arroje una excepción NoImplementedException en los demás.
Esto es una cuestión de uso. Si no usa la interfaz, o sabe que su código no usará la interfaz, no invierta tiempo en esto, ya que no necesita invertir tiempo en código redundante.
Trabaje para la tarea en cuestión y mantenga un buen rastro para que otros lo sigan si desean usar la interfaz.
Muchas interfaces en Java no están implementadas al máximo.
Este es el enfoque de Apache para las cosas: http://commons.apache.org/lang/api-2.4/org/apache/commons/lang/NotImplementedException.html
fuente