Uno se topa con esta frase cuando lee sobre patrones de diseño.
Pero no lo entiendo, ¿podría alguien explicarme esto?
oop
design-patterns
interface
software-design
ooad
never_had_a_name
fuente
fuente
Respuestas:
Codificación contra medios de interfaz, el código del cliente siempre contiene un objeto de interfaz que es suministrado por una fábrica. Cualquier instancia devuelta por la fábrica sería del tipo Interfaz que cualquier clase de candidato de fábrica debe haber implementado. De esta manera, el programa cliente no está preocupado por la implementación y la firma de la interfaz determina lo que se pueden hacer todas las operaciones. Esto se puede usar para cambiar el comportamiento de un programa en tiempo de ejecución. También le ayuda a escribir programas mucho mejores desde el punto de vista del mantenimiento.
Aquí hay un ejemplo básico para ti.
EDITAR
He actualizado el ejemplo anterior y agregué una
Speaker
clase base abstracta . En esta actualización, agregué una función a todos los altavoces a "SayHello". Todos los oradores hablan "Hola Mundo". Entonces esa es una característica común con una función similar. Consulte el diagrama de clase y encontrará queSpeaker
laISpeaker
interfaz de implementación de clase abstracta marca elSpeak()
resumen como lo que significa que cada implementación de Speaker es responsable de implementar elSpeak()
método, ya que varía deSpeaker
aSpeaker
. Pero todos los oradores dicen "Hola" por unanimidad. Entonces, en la clase abstracta Speaker definimos un método que dice "Hola Mundo" y cadaSpeaker
implementación derivará elSayHello()
método.Considere un caso en el
SpanishSpeaker
que no se puede decir hola, por lo que en ese caso puede anular elSayHello()
método para hispanohablantes y generar una excepción adecuada.Y podríamos lograr este comportamiento simplemente agregando un orador de clase abstracta base y algunas modificaciones menores en cada implementación, dejando el programa original sin cambios. Esta es una característica deseada de cualquier aplicación y hace que su aplicación sea fácilmente mantenible.
fuente
List
como tipo, aún podría estar asumiendo que el acceso aleatorio es rápido al llamar repetidamenteget(i)
.Piense en una interfaz como un contrato entre un objeto y sus clientes. Es decir, la interfaz especifica las cosas que puede hacer un objeto y las firmas para acceder a esas cosas.
Las implementaciones son los comportamientos reales. Digamos, por ejemplo, que tiene un método sort (). Puede implementar QuickSort o MergeSort. Eso no debería importarle al ordenamiento del código del cliente siempre que la interfaz no cambie.
Las bibliotecas como la API de Java y .NET Framework hacen un uso intensivo de las interfaces porque millones de programadores usan los objetos provistos. Los creadores de estas bibliotecas deben tener mucho cuidado de no cambiar la interfaz de las clases en estas bibliotecas porque afectará a todos los programadores que usan la biblioteca. Por otro lado, pueden cambiar la implementación tanto como quieran.
Si, como programador, codifica contra la implementación, tan pronto como cambie, su código dejará de funcionar. Así que piense en los beneficios de la interfaz de esta manera:
fuente
Significa que debe intentar escribir su código para que use una abstracción (clase abstracta o interfaz) en lugar de la implementación directamente.
Normalmente, la implementación se inyecta en su código a través del constructor o una llamada a un método. Por lo tanto, su código conoce la interfaz o la clase abstracta y puede llamar a cualquier cosa que esté definida en este contrato. Como se usa un objeto real (implementación de la interfaz / clase abstracta), las llamadas operan en el objeto.
Este es un subconjunto de
Liskov Substitution Principle
(LSP), la L de losSOLID
principios.Un ejemplo en .NET sería codificar con en
IList
lugar deList
oDictionary
, por lo que podría usar cualquier clase que se implementeIList
indistintamente en su código:Otro ejemplo de la Biblioteca de clase base (BCL) es la
ProviderBase
clase abstracta: esto proporciona cierta infraestructura y, lo que es más importante, significa que todas las implementaciones de proveedores se pueden usar indistintamente si se codifica contra ella.fuente
Si tuviera que escribir una Clase de automóvil en la era de Combustión de automóviles, entonces hay una gran posibilidad de que implemente oilChange () como parte de esta Clase. Pero, cuando se introducen los autos eléctricos, estaría en problemas ya que no hay cambio de aceite involucrado para estos autos, ni implementación.
La solución al problema es tener una interfaz performMaintenance () en la clase Car y ocultar detalles dentro de la implementación adecuada. Cada tipo de automóvil proporcionaría su propia implementación para performMaintenance (). Como propietario de un automóvil, todo lo que tiene que hacer es realizar mantenimiento () y no preocuparse por adaptarse cuando hay un CAMBIO.
Explicación adicional: usted es propietario de un automóvil que posee varios automóviles. Esculpe el servicio que desea externalizar. En nuestro caso, queremos externalizar el trabajo de mantenimiento de todos los automóviles.
No debe preocuparse por asociar el tipo de automóvil con el proveedor de servicios. Simplemente especifique cuándo desea programar el mantenimiento e invocarlo. La compañía de servicio apropiada debe participar y realizar el trabajo de mantenimiento.
Enfoque alternativo.
Invocas el trabajo y lo haces tú mismo. Aquí va a hacer el trabajo de mantenimiento apropiado.
¿Cuál es la desventaja del segundo enfoque? Es posible que no sea el experto en encontrar la mejor manera de realizar el mantenimiento. Su trabajo es conducir el automóvil y disfrutarlo. No estar en el negocio de mantenerlo.
¿Cuál es la desventaja del primer enfoque? Existe la sobrecarga de encontrar una empresa, etc. A menos que sea una empresa de alquiler de automóviles, puede que no valga la pena el esfuerzo.
fuente
Esta afirmación trata sobre el acoplamiento. Una razón potencial para usar la programación orientada a objetos es la reutilización. Entonces, por ejemplo, puede dividir su algoritmo entre dos objetos colaboradores A y B. Esto podría ser útil para la creación posterior de otro algoritmo, que podría reutilizar uno u otro de los dos objetos. Sin embargo, cuando esos objetos se comunican (envían mensajes - métodos de llamada), crean dependencias entre sí. Pero si desea usar uno sin el otro, debe especificar qué debe hacer algún otro objeto C para el objeto A si reemplazamos B. Esas descripciones se denominan interfaces. Esto permite que el objeto A se comunique sin cambios con diferentes objetos que dependen de la interfaz. La declaración que mencionó dice que si planea reutilizar alguna parte de un algoritmo (o más generalmente un programa), debe crear interfaces y confiar en ellas,
fuente
Como han dicho otros, significa que su código de llamada solo debe saber sobre un padre abstracto, NO sobre la clase de implementación real que hará el trabajo.
Lo que ayuda a entender esto es el POR QUÉ siempre debe programar en una interfaz. Hay muchas razones, pero dos de las más fáciles de explicar son
1) Prueba.
Digamos que tengo mi código de base de datos completo en una clase. Si mi programa conoce la clase concreta, solo puedo probar mi código ejecutándolo realmente en esa clase. Estoy usando -> para significar "habla con".
WorkerClass -> DALClass Sin embargo, agreguemos una interfaz a la mezcla.
WorkerClass -> IDAL -> DALClass.
Entonces, DALClass implementa la interfaz IDAL, y la clase trabajadora SOLO llama a través de esto.
Ahora, si queremos escribir pruebas para el código, podríamos crear una clase simple que simplemente actúe como una base de datos.
WorkerClass -> IDAL -> IFakeDAL.
2) reutilizar
Siguiendo el ejemplo anterior, digamos que queremos pasar de SQL Server (que utiliza nuestro DALClass concreto) a MonogoDB. Esto requeriría mucho trabajo, pero NO si lo hemos programado para una interfaz. En ese caso, simplemente escribimos la nueva clase DB y cambiamos (a través de la fábrica)
WorkerClass -> IDAL -> DALClass
a
WorkerClass -> IDAL -> MongoDBClass
fuente
Las interfaces describen las capacidades. cuando escriba código imperativo, hable sobre las capacidades que está utilizando, en lugar de tipos o clases específicos.
fuente