Pergunta

Atualmente, estou codificação de um simples Camada de acesso a dados, e eu queria saber que tipo devo expor a outras camadas.

Eu estou indo para implementar internamente os dados como um List <>, mas eu lembro de ter lido algo sobre não expor o tipo de lista para os consumidores se não for necessário.

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

Você sabe por que (o Google não ajuda)? O que você costuma expor para esse tipo de coisa? IList? IEnumerable?

Foi útil?

Solução

Geralmente é melhor para expor a interface menos poderoso que o usuário pode ainda significativamente o trabalho com. Se o usuário só precisa de alguns dados enumeráveis, voltar IEnumerable<User>. Se isso não for suficiente, porque o usuário precisa para ser capaz de modificar a lista (atenção! Não deve muitas vezes ser o caso), retornar um IList<User>.

/ EDIT:

Joel faz uma pergunta válida em seu comentário: Por quê expor a interface menos poderosa em vez de conceder o poder máximo do usuário? (Parafraseado)

A idéia por trás disso é que o método de retornar os dados não pode esperar que o usuário modifique seu conteúdo: Outro método da classe ainda pode esperar que a lista a ser não-vazia após uma referência a ele foi devolvido. Imagine as remove de usuários todos os dados da lista. O outro método agora tem de fazer uma verificação adicional que ELE poderia ter sido desnecessário.

Mais importante, isso expõe partes da implementação interna através do tipo de retorno. Se eu precisar alterar a implementação no futuro para que ele não usa um recipiente IList, eu tenho um problema: eu nem necessidade de alterar o contrato método, introduzindo uma mudança de quebra de construção. Ou eu preciso para copiar os dados em um recipiente lista.

Por exemplo, imagine que uma implementação eficiente usa um dicionário e apenas retorna a coleção Values que não implementa IList.

Outras dicas

Definitivamente um ISomething. Usando uma interface irá reduzir o acoplamento e torná-lo mais fácil de alterar detalhes de implementação da sua camada de dados no caminho. Qual interface depende das circunstâncias. IList é bom, mas às vezes você pode precisar de funcionalidade ICollection ou deseja especificar valores que são somente leitura.

Você deve pensar cuidadosamente antes de retornar IEnumerable. Se o código subjacente está usando "rendimento" para gerar o IEnumerable, ou está usando LINQ, então você vai acabar segurando aberta quaisquer recursos utilizados.

Você deve copiar o IEnumerable em outro IEnumerable antes de devolvê-lo. Ao usar IList, você faz isso uma exigência, para que ninguém possa inadvertidamente retornar um IEnumerable.

Por outro lado, retornando um IList implica para o chamador de que podem mudar a lista retornada.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top