Pergunta

Uma coisa que eu vejo em alguns aplicativos corporativos DDD que eu trabalho, é o uso de interfaces que são idênticas às entidades de domínio, com um mapeamento um-para-um de propriedades e funções. Na verdade um objeto de domínio é sempre usado por ele é um-para-um interface, e todas as entidades de domínio tem uma interface de um-para-um em este modelo.

Por exemplo:

Conta objeto Domínio:

public class Account : IAccount
{
     public string Name {get;set;}
     //...some more fields that are also in IAccount
     public decimal Balance {get;set;}
}

E é interface de harmonização

public interface IAccount
{
   string Name {get;set;}
   //... all the fields in Account
   decimal Balance {get;set;}
}

Mas ultimamente eu me tornei cada vez mais convencido de que este é, de fato, um anti-padrão.
Corri-lo por alguns arquitetos na comunidade de fonte aberta, e eles dizem que isso é baseado em erros de projeto ou falhas, em algum lugar na cadeia de design.

Então, eu digo aos meus colegas que eles deveriam parar de interfaces de criação de objetos do domínio. Porque não há um propósito para eles, e você tem que atualizar a interface sempre que você atualizar as entidades de domínio.

Primeiro, a afirmação foi feita que essas interfaces fornecem 'dissociação', mas eu contador que porque as interfaces têm um relacionamento um-para-um com as entidades de domínio que eles realmente não fornecer qualquer dissociação, uma mudança para os meios de interface uma mudança na entidade de domínio e vice-versa.

O próximo pedido é que precisamos de interfaces para fins de teste. Meu contador é que Rhino-simulações prevê a zombaria e stubbing de classes concretas. Mas eles afirmam que Rhino-simulações tem problemas com classes concretas. Eu não sei se eu comprar que, mesmo que Rhino-simulações tem problemas com classes concretas, que não significa necessariamente que devemos usar interfaces para as entidades de domínio.

Então estou curioso:

Por que você tem interfaces de um-para-um para as suas entidades de domínio?

Por que não?

Por que é uma boa ou má prática?

Obrigado por ler!

Editar : Devo observar que eu usar interfaces o tempo todo, e eu acredito que, se ele é chamado para vou usar uma interface na queda de um chapéu. Mas eu estou especificamente referindo-se a entidades de domínio com interfaces de um-para-um.

Foi útil?

Solução

É uma má prática como descrito, mas ...

Não há nenhuma razão específica que suas interfaces precisa ser diferente do que seus entidades de domínio; às vezes é realmente o mapeamento direita. Mas é suspeito de que é sempre o caso. O ponto de preocupação há uma questão de haver ou não as interfaces foram realmente concebidos, ou se eles foram apenas fique no lugar por falta de tempo / preguiça.

Para usar o exemplo, o IAccount interface que descrevem expõe getters e setters no objeto de conta; parece um pouco estranho e improvável que tudo que usa uma conta terá uma necessidade para definir o saldo da conta, e que essa permissão implícita é especificado nesse nível de interface. Não há lugar em seu sistema onde você quiser verificar apenas, mas não definir o saldo da conta?

Outras dicas

A maior razão para sempre especificando o domínio objetos como interfaces em vez de diretamente como aulas é dar-lhe um grau de liberdade sobre a implementação. No seu exemplo você só tem um tipo de IAccount, por isso é um pouco redunant.

Mas e se você tivesse, por exemplo:

public class Account : IAccount { ... }       // Usual account, persistent
public class MockAccount : IAccount { ... }   // Test mock object
public class TransAccount : IAccount { ... }  // Account, not persistent
public class SimAccount : IAccount { ... }    // Account in a performance sim

e assim por diante?

Ao definir os objetos de domínio como interfaces, você pode substituir as implementações sem perturbar a sua definição de domínio.

Em geral, se minhas aulas não vão ser parte de um padrão de design como estratégia ou visitante não adicionar interfaces.

Adicionando interfaces é realmente útil para padrões de projeto como Estratégia e Visitantes, mas nesses casos eu não copiar carbono os getters e setters das classes de domínio. Em vez disso, criar interfaces que são específicos para as interfaces de design padrão que eu crio.

interface SomeStrategy {
   void doSomething(StrategyData data);
}

interface StrategyData {
   String getProperty1();

   String getProperty2();
} 

Isso me permite deixar as classes de domínio implementar essas interfaces, ou para usar o padrão Adapter. Acho que esta é uma abordagem mais limpo tanto que apenas a criação de interfaces para o bem dela.

O projeto deve sempre reduzir a incerteza. Criação de interfaces para o bem de não reduzir a incerteza, na verdade, provavelmente, aumenta a confusão, uma vez que não faz qualquer sentido.

One-to-One Interfaces sobre as entidades são um anti-padrão

James Gregory colocá-lo melhor do que eu aqui .

Eu concordo com você. Interfaces deve agir como um contrato, então não há nenhum valor de ter um-para-um interfaces com entidades de domínio. Pode ser útil se você gostaria de abstrair um determinado comportamento. Mas, isso vai funcionar em determinados casos.

Por que esta fracassou?

Acho que tem uma interface para um objeto de domínio, como disse Charlie Martin, me permite escolher a minha implementação.

Um exemplo fundamental é o identificador (object.Id) para um objeto, este será diferente dependendo de onde você armazenar esse objeto e a responsabilidade de criar ele pode ou não pode descansar na implementação dos dados mais tarde. No SQL Server que você pode ir para um autonumber, mas no armazenamento de tabelas Azure que você pode ir para um Guid, mas você não quer ter que mudar a lógica de negócios de vocês app porque você alterar o local onde você armazenar seus dados.

I podem ou não optar por ter o meu objeto de domínio persistiu, ou até mesmo usá-lo na camada de apresentação - que depende do âmbito do meu aplicativo que é melhor. Mas a adição de um conjunto de interfaces de domínio comuns em uma camada comum permite-me a escrever serviços contra eles e reutilizá-los novamente e novamente.

Gostaríamos de ir sobre o mesmo argumento sobre o que deve ser um endereço se não tivéssemos tem IAddress, novos programadores seria reescrever o material para cartões de crédito, se não fosse por ICreditCard.

O rótulo de anti-padrão é um mau uso da linguagem, é uma simplificação mais para descrever o valor de soluções para tarefas complexas e variadas.

Há um lugar para a maioria dos padrões até mesmo o caluniado Singleton, o que significa que não é um "anti-padrão", pelo menos tanto como o termo sugere.

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