2010-07-01 20 views
9

En el proyecto en el que estoy trabajando, he notado que para cada clase de entidad hay una interfaz. Parece que la motivación original fue exponer interfaces a otros proyectos/soluciones.C# - ¿Agregar una interfaz sistemáticamente es una buena práctica?

Encuentro esto completamente inútil, y no veo el sentido de crear una interfaz para cada clase. Por cierto, esas clases no tienen ningún método solo propiedades y no implementan la misma interfaz.

¿Estoy equivocado? ¿O es una buena práctica?

Thx

+2

¿Tiene algunos ejemplos? Recomiendo leer esta respuesta ace: http://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface/384067#384067 –

+0

Si son clases COM, esto es normal (léase: tipo de requerido). –

+0

Posible duplicado de [¿Es la mejor práctica extraer una interfaz para cada clase?] (Http://stackoverflow.com/questions/3036749/is-it-the-best-practice-to-extract-an-interface- for-every-class) – DavidRR

Respuesta

6

Puede haber más en la configuración que la descrita aquí que justifique la sobrecarga de las interfaces. Generalmente son muy útiles para la inyección de dependencia y la separación general de preocupaciones, pruebas unitarias y burlas, etc. Es muy posible que no estén siendo utilizados para este propósito (o cualquier otro propósito constructivo, realmente) en su entorno, aunque .

¿Este código se ha generado, o se crearon manualmente? Si el primero, sospecho que la herramienta que los genera lo está haciendo para prepararse para tal uso si el desarrollador estuviera tan inclinado. Si esto último, ¿tal vez el diseñador original tenía algo en mente?

Para mis propias "mejores prácticas", casi siempre hago desarrollo basado en interfaces. En general, es una buena práctica separar preocupaciones entre sí y utilizar las interfaces como contratos entre ellas.

+0

Prefiero YAGNI, pero creo que sus posibles razones para las interfaces en este proyecto en particular son acertadas. – Marc

+2

En general, estoy de acuerdo con YAGNI. Como desarrollador de empresa, mi enfoque siempre es "bueno para el negocio" y "bueno para el código". Por supuesto, el negocio no siempre entiende que los dos son a menudo uno y el mismo :) – David

7

que tienden a crear una interfaz para casi todas las clases principalmente a causa de la unidad de pruebas - si se utiliza la inyección de dependencias, y quiere comprobar unidad de una clase que depende de la clase en cuestión, que la forma estándar es para burlarse de una instancia de la clase en cuestión (utilizando uno de los marcos de burla, por ejemplo, Rhino-Mocks). Sin embargo, prácticamente solo es posible solo para interfaces, no para implementaciones concretas (sí, teóricamente puedes burlar una clase concreta, pero hay muchas limitaciones dolorosas).

4

Es útil para las pruebas.

Un método puede tomar un parámetro del tipo ISomething, y puede ser SqlSomething o XmlSomething, donde ISomething es la interfaz, y SqlSomething y XmlSomething son clases que implementan la interfaz, dependiendo de si está haciendo pruebas (pasa XmlSomething en este caso) o ejecutar la aplicación (SqlSomething).

Además, al construir un proyecto universal, que puede funcionar en cualquier base de datos, pero no está utilizando una herramienta ORM como LINQ (tal vez porque el motor de base de datos puede no ser compatible con LINQ a SQL), defina interfaces, con métodos que lo usas en la aplicación. Más adelante, los desarrolladores implementarán las interfaces para trabajar con la base de datos, crearán la clase MySQLProductRepository, la clase PostgreSQLProductRepository, que heredarán la misma interfaz, pero tienen diferentes funcionalidades.

En el código de la aplicación, cualquier método toma un parámetro un objeto de repositorio de tipo IProductRepository, que puede ser cualquier cosa.

1

Si esas clases solo tienen propiedades, las interfaces no agregan mucho valor porque no se está abstrayendo ningún comportamiento.

Las interfaces pueden ser útiles para la abstracción, por lo que la implementación puede ser burlada en pruebas unitarias. Pero en una aplicación bien diseñada, las entidades comerciales/de dominio deben tener muy pocas razones para burlarse. Los servicios de negocios/dominio, por otro lado, son un excelente candidato para la abstracción de la interfaz.

He creado interfaces para mis entidades una vez, y no agregó ningún valor. Solo me hizo darme cuenta de que mi diseño estaba mal.

1

En mi humilde opinión, parece que escribir interfaces sin ningún motivo es inútil. No se puede tener una mente totalmente cerrada, pero en general hacer cosas que no son inmediatamente útiles tienden a acumularse como desperdicio.

Me viene a la mente el concepto ágil de agregar valor o tomar valor.

¿Qué sucede cuando los quita? Si nada entonces ... ¿para qué están allí?

Como nota al margen. Las interfaces son extremadamente útiles para Rhino Mocks, inyección de dependencia, etc. ...

5

La exposición de interfaces públicamente tiene valor en la creación de una arquitectura débilmente acoplada, basada en el comportamiento.

Crear una interfaz para cada clase, especialmente si la interfaz solo expone cada método público que la clase tiene en una sola interfaz, es una mala implementación del concepto y (en mi experiencia) conduce a código más complejo y no mejora en arquitectura

+0

+1 - Totalmente esto. Las interfaces son una herramienta. Al igual que cualquier herramienta, tienen buenos usos y usos no tan buenos. Y este ejemplo no suena bien. – GalacticCowboy

+0

No es tan malo si la interfaz existe antes que la clase, pero solo crear 'IFoo' para cada clase' Foo' no es muy útil. – kyoryu

0

Para pruebas unitarias, es interfaces en todas partes o métodos virtuales en todas partes.

veces echo de menos de Java :)

1

Parece ser una interfaz es superior a una clase base abstracta sobre todo si/cuando es necesario disponer de una clase que implementa la interfaz, pero hereda de otra clase base. La herencia múltiple no está permitida, pero sí lo son las implementaciones de múltiples interfaces.

La advertencia principal que veo con el uso de interfaces en lugar de clases abstractas (más allá del código fuente adicional requerido) es que cambiar cualquier cosa en una interfaz requiere la recompilación de cualquier código que use esa interfaz. Por el contrario, agregar miembros públicos a una clase base generalmente solo requiere la recompilación de la clase base. (*)

(*) Debido a la forma en que se manejan los métodos de extensión, agregar miembros a una clase no será "necesario" recompilando código que usa esa clase, pero puede causar código que usa métodos de extensión en la clase para cambiar el significado la próxima vez que se recompila (el código que usa el método de extensión).

1

No hay forma de predecir el futuro y ver si va a necesitar programar contra una interfaz en el camino. Pero si más tarde decide hacer que todo use una interfaz y, por ejemplo, una fábrica para crear instancias de tipos desconocidos (cualquier tipo que implemente la interfaz), entonces es más rápido restringir a todos a programar contra una interfaz y una fábrica por adelantado que reemplazar referencias a MyImpl con referencias a IMyInterface más tarde, etc.

Así que cuando se escribe un nuevo software, es una decisión juzgar si se programa contra una interfaz o una implementación, a menos que esté familiarizado con lo que es probable que suceda ese tipo de software basado en experiencias previas.

Por lo general, lo mantengo "in flux" por un tiempo, tenga o no una interfaz, una clase base o ambas, e incluso si la clase base es abstracta (generalmente lo es). Trabajaré en un proyecto (por lo general, una solución de Visual Studio con entre 3 y 10 proyectos) por un tiempo (un par de días, quizás) antes de refactorizar y/o solicitar una segunda opinión. Una vez que se llega a una decisión final y se refactoriza y prueba el código, les digo a mis colegas desarrolladores que está listo para su uso.

Cuestiones relacionadas