2009-12-28 13 views
13

Quiero consolidar mi comprensión del concepto de "codificación a la interfaz". Según lo entiendo, uno crea interfaces para delinear la funcionalidad esperada, y luego implementa estos "contratos" en clases concretas. Para usar la interfaz , puede simplemente llamar a los métodos en una instancia de la clase concreta.¿Codificando a las interfaces?

El beneficio obvio es conocer la funcionalidad proporcionada por la clase concreta, independientemente de su implementación específica.

Basado en lo anterior:

  1. ¿Hay algunas falacias en mi comprensión de la "codificación para las interfaces"?
  2. ¿Hay alguna ventaja de codificar en las interfaces que me perdí?

Gracias.

+0

Esto no es una 'respuesta', pero dos motivaciones concretas para las interfaces (que pueden ayudar a su 'AHA' momento), y los que utilizo todos los días son la inyección de dependencias (el marco de la Unidad Microsoft es fantástico para este) y fábricas (y patrones de diseño en general). Consulte http://en.wikipedia.org/wiki/Dependency_injection y http://en.wikipedia.org/wiki/Factory_object – Joe

+0

http://stackoverflow.com/questions/48605/why-do-most-java-system -architects-insiste-en-primera-codificación-en-una-interfaz – SwDevMan81

Respuesta

13

Sólo una posible corrección:

Para utilizar la interfaz simplemente se puede llamar a los métodos en una instancia de la clase concreta.

Uno podría llamar a los métodos de referencia del tipo de interfaz, que pasa a utilizar la clase concreta como la aplicación:

List<String> l = new ArrayList<String>(); 
l.add("foo"); 
l.add("bar"); 

Si ha decidido cambiar a otra aplicación de lista, el código funciona cliente sin cambio:

List<String> l = new LinkedList<String>(); 

Esto es especialmente útil para ocultar los detalles de implementación, proxies de generación de auto, etc.

Encontrará que los marcos como y fomentan la programación en una interfaz. Es la base para ideas como programación , proxies generados automáticamente para la gestión de transacciones, etc.

+0

Supongo que ArrayList implementa la clase List? No estoy seguro de qué idioma está proporcionando un ejemplo de. Supongo que podría decir Lista l = new SomeOtherList(); ? – JonH

+1

Es Java - List es una interfaz implementada por ArrayList. Sí, podrías tener ese punto de referencia para un nuevo tipo de Lista si lo deseas. – duffymo

+0

+1 por decirnos cuál es la lista. Ayuda porque muchas personas no son desarrolladores de Java (yo soy uno). Entonces, cuando vi List l = new ArrayList() pensé que esperar un minuto List esperaba donde T es un tipo (en C# eso es). Así que pensé en cómo está asignando una ArrayList (que también podría ser C#) a una clase de lista. De nuevo, gracias por señalar eso. – JonH

1

No mencionó la parte sobre cómo obtener una implementación de la interfaz, que es importante. Si crea una instancia explícita de la clase de implementación con un constructor, entonces su código está vinculado a esa implementación. Puedes utilizar una fábrica para obtener una instancia para ti, pero luego estás tan atado a la fábrica como antes a la clase de implementación. Su tercera alternativa es usar la inyección de dependencia, que consiste en conectar de fábrica el objeto de implementación al objeto que lo utiliza, en cuyo caso se evita que la clase que utiliza el objeto esté vinculada a la clase implementadora o a una fábrica.

4

La principal ventaja es que el uso de una interfaz combina libremente una clase con sus dependencias. A continuación, puede cambiar una clase o implementar una nueva implementación de interfaz concreta sin tener que cambiar las clases que dependen de ella.

2

El objetivo de la codificación contra interfaces es desacoplar su código de la implementación concreta en uso. Es decir, su código no hará suposiciones sobre el tipo concreto, solo la interfaz. En consecuencia, la implementación concreta se puede intercambiar sin necesidad de ajustar su código.

0

creo que puede haber hecho alusión a esto, pero creo que uno de los mayores beneficios de la codificación de una interfaz es que usted está rompiendo la dependencia de la aplicación concreta. Puede lograr un acoplamiento flexible y facilitar el cambio de implementaciones específicas sin cambiar mucho el código. Si solo estás aprendiendo, echaría un vistazo a varios design patterns y cómo resuelven problemas mediante la codificación de interfaces. Leer el libro Head First: Design Patterns realmente me ayudó a hacer clic para mí.

4

Para utilizar la interfaz, simplemente puede llamar a los métodos en una instancia de la clase concreta.

Normalmente, usted tendría una variable de tipo para el tipo de interfaz, lo que permite sólo el acceso a los métodos definidos en la interfaz.

El beneficio obvio es conocer la funcionalidad proporcionada por la clase concreta, independientemente de su implementación específica.

Tipo de. Lo más importante, le permite escribir API que toman parámetros con tipos de interfaz. Los usuarios de la API pueden pasar sus propias clases (que implementan esas interfaces) y su código funcionará en esas clases aunque aún no existieran cuando se escribió (como java.util.Arrays.sort() capaz de ordenar cualquier cosa que implemente Comparable o viene con un adecuado Comparator).

Desde una perspectiva de diseño, interfaces permiten/hacer cumplir una clara separación entre los contratos de API y detalles de implementación.

5

Su comprensión parece estar en lo cierto. Su compañero de trabajo simplemente pasó por su escritorio y tiene todas las últimas fotos de la fiesta de Navidad protagonizada por su jefe borracho cargado en su unidad de memoria. Su compañero de trabajo y usted no lo piensa dos veces acerca de cómo funciona esta unidad de disco, para usted es una caja negra, pero usted sabe que funciona debido a la interfaz USB .

No importa si se trata de una SanDisk o un titanio (ni siquiera seguro de que es una marca), el tamaño/el color no importa tampoco. De hecho, lo único que importa es que no está roto (legible) y que se conecta a USB.

Su memoria USB se rige por un contrato, se trata esencialmente de una interfaz. Uno puede asumir que cumple algunas funciones muy básicas:

  1. Se conecta al USB
  2. se rige por el método de contrato CopyDataTo:

    interfaz IUSB pública { vacío CopyDataTo (somepath cadena); // usado para copiar datos de la unidad de miniatura para ... }

  3. se rige por el método de contrato CopyDataFrom:

    pública Interfaz IUSB { CopyDataFrom vacío(); // utilizar para copiar datos desde el PC a la unidad miniatura }

bien quizás no esos métodos, pero la interfaz deIUSB es sólo un contrato que los vendedores miniatura de la unidad tienen que cumplir para garantizar la funcionalidad a través varias plataformas/vendedores. Así SanDisk hace que su dispositivo en miniatura por la interfaz:

public class SanDiskUSB : IUSB 
{ 
    //todo: define methods of the interface here 
} 

Ari, creo que ya tiene un conocimiento sólido (de lo que suena) acerca de cómo las interfaces de trabajo.

0

Según tengo entendido, uno crea interfaces para delinear la funcionalidad esperada, y luego implementa estos "contratos" en clases concretas.

El único tipo de mutación que veo en su forma de pensar es esto: llamará a los contratos esperados, no a la funcionalidad esperada. La funcionalidad se implementa en las clases concretas. La interfaz solo indica que podrá llamar a algo que implemente la interfaz con las firmas de métodos esperados. La funcionalidad está oculta del objeto que llama.

Esto le permitirá estirar su pensamiento en polimorfismo de la siguiente manera.

SoundMaker sm = new Duck();<br/> 
SoundMaker sm1 = new ThunderousCloud(); 

sm.makeSound(); // quack, calls all sorts of stuff like larynx, etc.<br/> 
sm1.makeSound(); // BOOM!, completely different operations here... 
+0

Odio ejemplos como este solo porque creo que confunden al lector. Las explicaciones son definitivamente útiles. En este caso, supongo que SoundMaker es una clase base y makeSound es un método abstracto de la clase SoundMaker. Debido a que es un método abstracto, el objeto Duck define esta función makeSound para quack y el ThunderousCloud define esta función para ir a kaboom. Lo siento, pero para los principiantes cuando veo una clase de auto o clase de mamíferos, ¡solo me molesta! SoundMaker también podría ser una interfaz en este caso, que es lo que creo que quiere decir. – JonH

+0

JonH: Gracias y estoy de acuerdo. Debería haber incluido SoundMaker como una interfaz explícita aquí para demostrarlo. –