Raramente uso interfaces y las encuentro comunes en otros códigos.
También creo subclases y superclases (mientras creo mis propias clases) rara vez en mi código.
- ¿Es algo malo?
- ¿Sugerirías cambiar este estilo?
- ¿Este estilo tiene algún efecto secundario?
- ¿Es esto porque no he trabajado en proyectos grandes?
programming-practices
coding-style
interfaces
jineesh joseph
fuente
fuente
Respuestas:
Hay varias razones por las que es posible que desee utilizar interfaces:
http://msdn.microsoft.com/en-us/library/3b5b8ezk(v=vs.80).aspx
Las interfaces son como cualquier otra cosa en la programación. Si no los necesita, no los use. Los he visto utilizados ampliamente como una cuestión de estilo, pero si no necesita las propiedades y capacidades especiales que proporciona una interfaz, no veo el beneficio de usarlos "solo porque".
fuente
Tanto la herencia de clase como las interfaces tienen su lugar. Herencia significa "es un", mientras que una interfaz proporciona un contrato que define cómo se comporta "algo".
Yo diría que usar interfaces con más frecuencia no es una mala práctica en absoluto. Actualmente estoy leyendo "Efectivo C # - 50 formas específicas para mejorar su C #" por Bill Wagner. El artículo número 22 establece, y una cita, "Prefiero definir e implementar interfaces a la herencia".
En general, uso clases base cuando necesito definir una implementación específica de comportamiento común entre tipos relacionados conceptualmente. Más a menudo uso interfaces. De hecho, normalmente empiezo definiendo una interfaz para una clase cuando empiezo a crear una ... incluso si al final no compilo la interfaz, encuentro que ayuda comenzar definiendo la API pública de la clase clase desde el principio. Si descubro que tengo varias clases implementando la interfaz, y la lógica de implementación es idéntica, solo entonces me preguntaré si tendría sentido implementar una clase base común entre los tipos.
Un par de citas del libro de Bill Wagners ...
todas las clases derivadas incorporan inmediatamente ese comportamiento. Agregar un miembro a una interfaz rompe todas las clases que implementan esa interfaz. No contendrán el nuevo método y ya no se compilarán. Cada implementador debe actualizar ese tipo para incluir al nuevo miembro. Elegir entre una clase base abstracta y una interfaz es una cuestión de cómo apoyar mejor sus abstracciones a lo largo del tiempo. Las interfaces son fijas: libera una interfaz como un contrato para un conjunto de funcionalidades que cualquier tipo puede implementar. Las clases base se pueden extender con el tiempo. Esas extensiones se convierten en parte de cada clase derivada. Los dos modelos se pueden mezclar para reutilizar el código de implementación mientras se admiten múltiples interfaces ". No contendrán el nuevo método y ya no se compilarán. Cada implementador debe actualizar ese tipo para incluir al nuevo miembro. Elegir entre una clase base abstracta y una interfaz es una cuestión de cómo apoyar mejor sus abstracciones a lo largo del tiempo. Las interfaces son fijas: libera una interfaz como un contrato para un conjunto de funcionalidades que cualquier tipo puede implementar. Las clases base se pueden extender con el tiempo. Esas extensiones se convierten en parte de cada clase derivada. Los dos modelos se pueden mezclar para reutilizar el código de implementación mientras se admiten múltiples interfaces ". No contendrán el nuevo método y ya no se compilarán. Cada implementador debe actualizar ese tipo para incluir al nuevo miembro. Elegir entre una clase base abstracta y una interfaz es una cuestión de cómo apoyar mejor sus abstracciones a lo largo del tiempo. Las interfaces son fijas: libera una interfaz como un contrato para un conjunto de funcionalidades que cualquier tipo puede implementar. Las clases base se pueden extender con el tiempo. Esas extensiones se convierten en parte de cada clase derivada. Los dos modelos se pueden mezclar para reutilizar el código de implementación mientras se admiten múltiples interfaces ". Libera una interfaz como un contrato para un conjunto de funcionalidades que cualquier tipo puede implementar. Las clases base se pueden extender con el tiempo. Esas extensiones se convierten en parte de cada clase derivada. Los dos modelos se pueden mezclar para reutilizar el código de implementación mientras se admiten varias interfaces ". Libera una interfaz como un contrato para un conjunto de funcionalidades que cualquier tipo puede implementar. Las clases base se pueden extender con el tiempo. Esas extensiones se convierten en parte de cada clase derivada. Los dos modelos se pueden mezclar para reutilizar el código de implementación mientras se admiten múltiples interfaces ".
"Las interfaces de codificación proporcionan una mayor flexibilidad a otros desarrolladores que la codificación a tipos de clase base".
"El uso de interfaces para definir API para una clase proporciona una mayor flexibilidad".
"Cuando su tipo expone propiedades como tipos de clase, expone toda la interfaz a esa clase. Usando interfaces, puede elegir exponer solo los métodos y propiedades que desea que los clientes usen".
"Las clases base describen e implementan comportamientos comunes a través de tipos concretos relacionados. Las interfaces describen piezas atómicas de funcionalidad que los tipos concretos no relacionados pueden implementar. Ambas tienen su lugar. Las clases definen los tipos que usted crea. Las interfaces describen el comportamiento de esos tipos como piezas funcionales. Si comprende las diferencias, creará diseños más expresivos que sean más resistentes frente al cambio. Utilice jerarquías de clase para definir tipos relacionados. Exponga la funcionalidad utilizando interfaces implementadas en esos tipos ".
fuente
Una cosa que no se ha mencionado es la prueba: en todas las bibliotecas de simulación C #, así como en algunas para Java, las clases no se pueden burlar a menos que implementen una interfaz. Esto lleva a muchos proyectos siguiendo las prácticas Agile / TDD para dar a cada clase su propia interfaz.
Algunas personas consideran esta mejor práctica, porque "reduce el acoplamiento", pero no estoy de acuerdo, creo que es solo una solución a una deficiencia en el lenguaje.
Creo que las interfaces se usan mejor cuando tienes dos o más clases que, de manera abstracta, hacen "lo mismo", pero de diferentes maneras.
Por ejemplo, el marco .Net tiene múltiples clases que almacenan listas de cosas , pero todas almacenan esas cosas de diferentes maneras. Por lo tanto, tiene sentido tener una
IList<T>
interfaz abstracta , que se puede implementar utilizando diferentes métodos.También debe usarlo cuando desee que 2+ clases sean intercambiables o reemplazables en el futuro. Si aparece una nueva forma de almacenar listas en el futuro,
AwesomeList<T>
suponiendo que haya utilizadoIList<T>
todo su código, cambiarlo para usarloAwesomeList<T>
solo significaría cambiar unas pocas docenas de líneas, en lugar de unos pocos cientos / mil.fuente
El resultado principal de no usar la herencia y las interfaces cuando son apropiadas es un acoplamiento estrecho . Esto puede ser un poco difícil de aprender a reconocer, pero generalmente el síntoma más obvio es que cuando haces un cambio, con frecuencia tienes que revisar muchos otros archivos para hacer cambios en un efecto dominó.
fuente
No, esto no es malo en absoluto. Deben usarse interfaces explícitas, si y solo si, dos clases con una interfaz común deben ser intercambiables en tiempo de ejecución. Si no es necesario que sean intercambiables, no haga que hereden. Es tan simple como eso. La herencia es frágil y debe evitarse siempre que sea posible. Si puedes evitarlo o usar genéricos en su lugar, entonces hazlo.
El problema es que, en lenguajes como C # y Java con genéricos débiles en tiempo de compilación, puede terminar violando DRY porque no hay forma de escribir un método que pueda manejar más de una clase a menos que todas las clases hereden de la misma base. Sin embargo, C # 4
dynamic
puede lidiar con esto.La cuestión es que la herencia es como variables globales: una vez que la agregue y su código dependa de ella, Dios lo ayudará a eliminarla. Sin embargo, puede agregarlo en cualquier momento, e incluso puede agregarlo sin alterar la clase base utilizando una especie de contenedor.
fuente
Sí, no (o muy raramente) usar interfaces es probablemente algo malo. Las interfaces (en sentido abstracto, y la construcción del lenguaje C # / Java es una aproximación bastante buena de ese sentido abstracto) definen puntos de interacción explícitos entre sistemas y subsistemas. Esto ayuda a reducir el acoplamiento y hace que el sistema sea más fácil de mantener. Al igual que con cualquier cosa que mejore la capacidad de mantenimiento, se vuelve más importante cuanto más grande es un sistema.
fuente
No he usado una interfaz en años. Por supuesto, esto se debe a que he estado programando casi exclusivamente en Erlang durante años y el concepto completo de una interfaz simplemente no existe. (Lo más cercano que obtienes es un "comportamiento" y eso no es realmente lo mismo a menos que entrecerres los ojos y los mires por el rabillo del ojo).
Entonces, realmente, su pregunta depende del paradigma (OOP en este caso) y, además, es realmente bastante dependiente del lenguaje (hay lenguajes OOP sin interfaces).
fuente
Si habla de usar Java, una razón para usar interfaces es que permiten el uso de objetos proxy sin bibliotecas de generación de código. Esto puede ser una ventaja sustancial cuando trabaja con un marco complejo como Spring. Además, algunas funcionalidades requieren interfaces: RMI es el ejemplo clásico de esto, ya que debe describir la funcionalidad que proporciona en términos de interfaces (que heredan de
java.rmi.Remote
) sin importar cómo las implemente.fuente
Las cosas están cambiando ( MS Moles ), pero la razón principal por la que creo que es bueno codificar casi exclusivamente las interfaces es que son fáciles de burlar y encajan naturalmente en una arquitectura IoC.
En mi opinión, solo debe trabajar con interfaces o DAO completamente tontos siempre que sea posible. Una vez que entras en esta mentalidad, y comienzas a usar una biblioteca que no se expone a través de interfaces y hace todo a través de objetos concretos, tengo que ser honesto, todo se siente un poco torpe.
fuente
Para proyectos antiguos, uno usa interfaces para evitar referencias circulares, porque las referencias circulares podrían convertirse en un gran problema de mantenimiento a largo plazo.
Malo:
No está mal:
Por lo general, A, B, PartOfClassB_AccessedByA implementado con archivos separados.
fuente
La programación basada en interfaz ayuda a hacer que el código sea más flexible y más fácil de probar. Las clases de implementación se pueden cambiar sin tocar el código del cliente [Flexibilidad]. Si bien probar el código uno puede reemplazar la programación real basada en la interfaz, ayuda a que el código sea más flexible y más fácil de probar. Las clases de implementación se pueden cambiar sin tocar el código del cliente [Flexibilidad]. Mientras se prueba el código uno, se puede reemplazar el objeto real con objetos simulados [Testability] .bject con objetos simulados [Testability].
fuente