Pregunta

Actualmente estoy codificando una capa de acceso a datos simple, y me preguntaba qué tipo debería exponer a las otras capas.

Voy a implementar internamente los datos como una lista < > ;, pero recuerdo haber leído algo sobre no exponer el tipo de lista a los consumidores si no es necesario.

public List<User> GetAllUsers() // non C# users: that means List of User :)

¿Sabes por qué (google no ayudó)? ¿Qué expones habitualmente para ese tipo de cosas? IList? IEnumerable?

¿Fue útil?

Solución

Por lo general, es mejor exponer la interfaz menos potente con la que el usuario aún puede trabajar de manera significativa. Si el usuario solo necesita algunos datos enumerables, devuelva IEnumerable < User > . Si eso no es suficiente porque el usuario necesita poder modificar la lista (¡atención! A menudo no debería ser el caso), devuelva un IList < User > .

/ EDITAR:

Joel hace una pregunta válida en su comentario: ¿Por qué exponer la interfaz menos poderosa en lugar de otorgarle al usuario la máxima potencia? (parafraseado)

La idea detrás de esto es que el método que devuelve los datos podría no esperar que el usuario modifique su contenido: otro método de la clase aún podría esperar que la lista no esté vacía después de que se devuelva una referencia. Imagine que el usuario elimina todos los datos de la lista. El otro método ahora tiene que hacer una verificación adicional de que ele podría haber sido innecesario.

Más importante aún, esto expone partes de la implementación interna a través del tipo de retorno. Si necesito cambiar la implementación en el futuro para que ya no use un contenedor IList , tengo un problema: necesito cambiar el contrato del método e introducir un cambio de ruptura de compilación. O necesito copiar los datos en un contenedor de listas.

Como ejemplo, imagine que una implementación eficiente utiliza un Diccionario y solo devuelve la colección Values ?? que no implementa IList .

Otros consejos

Definitivamente un IS algo. El uso de una interfaz reducirá el acoplamiento y facilitará el cambio de detalles de la implementación de la capa de datos en el futuro. Qué interfaz depende de las circunstancias. IList es bueno, pero a veces puede necesitar la funcionalidad ICollection o desea especificar valores que sean de solo lectura.

Debe pensar detenidamente antes de devolver IEnumerable. Si el código subyacente está usando " yield " para generar el IEnumerable, o está usando LINQ, entonces terminarás manteniendo abiertos los recursos utilizados.

Debe copiar el IEnumerable en otro IEnumerable antes de devolverlo. Al usar IList, usted hace de esto un requisito, para que nadie pueda devolver un IEnumerable sin darse cuenta.

Por otro lado, devolver una IList implica que la persona que llama puede cambiar la lista devuelta.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top