2010-01-26 13 views
21

Recientemente he visto algunas código C#, donde la declaración de interfaz y la implementación en la que en el mismo archivo, como esteInterfaz C# e implementación en el mismo archivo - ¿buena idea?

namespace MyNameSpace.Foo 
{ 
    public interface IFoo{ 
     void DoThis(); 
    } 
    public class Foo : IFoo { 
     public void DoThis(); 
    } 
} 

A primera vista parece mal tener declaración y aplicación en el mismo archivo, pero no son prácticos beneficios. p.ej. Cuando vaya a Definición en Visual Studio, la interfaz y la implementación se encuentran en el mismo archivo. Este enfoque no le impide tener otras implementaciones de la interfaz, como puede ser necesaria para la prueba unitaria. Para las interfaces que tendrán una sola implementación, creo que esto puede ser un enfoque pragmático.

¿Una idea buena o mala?

La extensión de la pregunta: ¿Cómo
qué la gente usa Visual Studio para navegar a una aplicación cuando se tiene una referencia de interfaz IFoo myFoo = FooFactory.getFoo(MY_FOO); Si hago clic derecho en IFoo y seleccione Ir a definición que puedo conseguir la declaración de interfaz. ¿Hay alguna manera de obtener la lista de implementaciones de IFoo ya que eso es a lo que realmente me interesa llegar?

+1

Excelentes comentarios hasta el momento. Creo que mi pregunta debería haberse ampliado para preguntar cómo las personas usan Visual Studio para navegar a una implementación cuando se tiene una referencia de interfaz: IFoo myFoo = FooFactory.getFoo (MY_FOO); Si hago clic derecho en IFoo y selecciono Ir a Definición, puedo obtener la declaración de interfaz ¿Hay alguna manera de obtener la lista de implementaciones de IFoo, ya que eso es lo que realmente me interesa? – Paul

Respuesta

33

Mi recomendación es seguir siempre una regla de un elemento por archivo .cs, ya sea una declaración de enumeración, interfaz o clase. El nombre del archivo .cs debe coincidir con el nombre de la cosa que contiene.

Regla simple, fácil de seguir. Usamos StyleCop internamente para vigilar esto.

Si combina este enfoque con un uso razonable de los espacios de nombres, entonces debería significar que su vista de explorador de soluciones en Visual Studio hace que sea más fácil navegar por los componentes en sus proyectos. Tenga en cuenta que ReSharper gives an alternative approach a esta navegación, pero usar esto no es para todos los gustos (y no todos pueden tener un complemento como ReSharper).

Travis G ha preguntado acerca de los puntos más finos, como los delegados y las declaraciones de EventArgs personalizadas. Como los EventArgs personalizados son clases, los pondría en sus propios archivos (nuevamente, manteniendo la regla simple). Delegados que declararía con la clase que los usa. Si descubrí que tenía muchos delegados que se utilizaron en muchos lugares, podría considerar colocarlos todos en un archivo Delegates.cs (a veces hago esto con constantes, en un archivo Consts.cs).

Sin embargo, algo de esto es ciertamente subjetivo y entrando en los dominios del software religious wars.

+1

Apoyo esto. Facilita la exploración del código, así como la búsqueda de una clase o interfaz en particular: basta con mirar el nombre del archivo. –

+2

Estoy contigo, pero ¿qué haces para cosas pequeñas como 'delegate's y' EventArg's personalizados? Normalmente los pongo en el mismo archivo, porque solo se usan en un solo lugar. –

+0

Asegúrate de estar satisfecho con lo que estás haciendo antes de soltar el reafilar. Es genial y lo uso, pero con gran poder viene una gran responsabilidad. –

13

Personalmente ...

Si una interfaz sólo es probable (a corto plazo) que se utilizará para una clase (como cuando se proporciona una interfaz para la inyección de dependencias) entonces voy a ponerlo en la parte superior de la archivo de clase. Durante el desarrollo (cuando la clase puede estar cambiando) es un PITA tener que cambiar dos archivos cada vez que cambia la superficie pública.

Por supuesto, si existe la posibilidad de que la interfaz sea implementada por más de una clase, entonces la coloco en un archivo separado.

+4

Sí, este es el escenario en el que estaba pensando, cuando solo está utilizando una interfaz por razones DI y no hay muchas posibilidades de que implemente otra definición de la interfaz aparte de una prueba impl. – Paul

+2

'Si una interfaz solo se usa para una clase, lo estás haciendo mal. Una interfaz no tiene valor aquí. Si varias clases no implementan la interfaz de inmediato, lo estás haciendo mal. Inyección de dependencias NO NECESITA interfaces sin sentido. Esto es un mito Use los tipos de concreto reales. –

+5

@ChrisMarisic ¿Cómo proporcionaría simulaciones de dependencias para Pruebas unitarias si dichas dependencias no son interfaces? – Holf

7

Tener la definición e implementación de la interfaz en el mismo archivo no tiene nada que ver con la prueba unitaria, ya que esa interfaz estará disponible de todos modos.

Generalmente comienzo con una interfaz simple e implementación en el mismo archivo. Cuando las cosas crecen, las divido cuando otro código necesita hacer referencia a esa interfaz.

4

Me limitaría a seguir la regla de "una clase, un archivo".Con clase también me refiero a interfaces, enumeraciones, etc.

¿Y qué hay de malo en poner el cursor sobre el nombre de la interfaz y presionar F12?

1

Seguro que no hace daño tenerlo así, y las herramientas como resharper colocarán la implementación debajo de la interfaz en el código. Sin embargo, también le dan la opción de mover la implementación a otro archivo.

Tiene razón, no le impide aprovechar los beneficios de las interfaces para la prueba unitaria, pero es posible que desee considerar poner las interfaces en otro ensamblaje por completo. De esta forma, podría programar contra interfaces e intercambiar implementaciones a voluntad, dándole más separación. Como siempre, no hay una respuesta correcta o incorrecta, todo se reduce a lo que estás tratando de lograr.

+1

Un buen consejo para poner interfaces en un ensamble separado (proyecto), que también funciona bien para mí. – Paul

0

Hago eso en Java para interfaces pequeñas con pocos métodos. En este caso, proporciono una o más implementaciones básicas en el archivo de interfaz.

Esto evita clases pequeñas dispersas.

Pero no puedo decir si es una mala o las mejores prácticas, aunque mis compañeros de trabajo nunca se quejaron.

5

Considero que esta es una mala idea.

Mantenga la interfaz y la implementación separadas. De lo contrario, hay posibilidades de desordenar el diseño. Incluya el archivo y obtenga automáticamente la implementación incluso si solo desea la interfaz, luego accidentalmente (porque es conveniente) use el Impl en lugar de la interfaz y, por supuesto, cierre de acoplamiento.

Cuestiones relacionadas