Programação contra interfaces: você escreve interfaces para todas as classes de seu domínio?

StackOverflow https://stackoverflow.com/questions/152077

  •  02-07-2019
  •  | 
  •  

Pergunta

Eu concordo, que a programação contra interfaces é uma boa prática. Na maioria dos casos em "Interface" Java neste sentido significa a interface de construção de linguagem, de modo que você escreve uma interface e uma classe de implementação e que você use a interface em vez da classe de implementação na maioria das vezes.

Gostaria de saber se esta é uma boa prática para escrever modelos de domínio também. Assim, por exemplo, se você tem uma classe de domínio do cliente e cada cliente pode ter uma lista de pedidos, você geralmente também interfaces de gravação ICustomer e IOrder. E também ao cliente ter uma lista de IOrders em vez de ordens? Ou será que você usar interfaces no modelo de domínio, apenas se for realmente impulsionada pelo domínio, por exemplo, você tem pelo menos dois tipos diferentes de ordens? Em outras palavras, você usaria interfaces, devido às necessidades única técnicos no modelo de domínio, ou apenas quando é realmente apropriado em relação ao domínio real?

Foi útil?

Solução

interfaces de escrever "apenas porque" parece-me um desperdício de tempo e energia, para não mencionar uma violação do KISS-princípio da.

Eu escrevo-los quando eles são realmente úteis na representação de comportamento comum de classes relacionadas, e não apenas como um arquivo de cabeçalho fantasia.

Outras dicas

Não mais de projetar seu sistema. Se você descobrir que você tem vários tipos de ordens e acho que é apropriado para declarar uma interface para ordens do que refatorar-lo quando surgir a necessidade. Para os modelos de domínio, a probabilidade é alta que a interface específica vai mudar muito ao longo do tempo de vida de desenvolvimento, por isso raramente é útil para escrever uma interface inicial.

Interfaces são uma excelente forma de isolar os componentes para fins de teste de unidade e administração geral de dependência. Dizendo que, muitas vezes eu prefiro classes abstratas assim, pelo menos algum do comportamento comum é descarregado lá ao invés de forçar um pouco da duplicação que as interfaces trazer. IDEs modernas, é rápido e fácil para gerar interfaces de forma que eles não são que muito trabalho: -)

Não, eu só usar interfaces em objetos de domínio para mantê-los de baixo acoplamento. Para mim, o gancho principal de desenvolver o meu próprio código com interfaces é que eu posso facilmente criar simulações ao fazer o teste da unidade. Eu não vejo o ponto de zombar objetos de domínio, como eles não têm as mesmas dependências que uma camada de serviço ou classe camada DAO teria.

Isto certamente não significa a desviar-se de usar Interfaces em objetos de domínio. Use sempre que necessário. Por exemplo, ultimamente tenho vindo a trabalhar em um webapp onde diferentes tipos de objetos de domínio correspondem a páginas permalink no qual os usuários podem deixar comentários. Então, cada um destes objetos de domínio agora implementar a interface "commentable". Todo o código-base comentário é então programado para a interface commentable vez do objetos de domínio.

Eu recomendo ficar magra e ágil - não fazer nada até que você precisa para fazê-lo, então deixe o seu IDE fazer a refatoração para você quando você precisar dele.

Sua bastante triviais no IDEA / eclipse para transformar uma classe concreta em uma interface quando você decidir que precisa de um.

Em seguida, use a injeção de dependência com Primavera ou Guice se você tiver muitas implementações da interface para injetar nos lugares em seu código que você está usando 'novo'

Na verdade, esta questão é um exemplo do equívoco comum sobre a "programação contra interfaces".

Você vê, este é um princípio muito bom, mas ele não significa que muitas pessoas pensam que significa!

"Programa para uma interface, não uma implementação" (do livro GoF) significa exatamente isso, não que você deve sair de seu caminho para criar interfaces separadas para tudo. Se você tem um objeto ArrayList, em seguida, declarar o tipo / parâmetro / retorno variável / campo como sendo do tipo List. o código do cliente, então, apenas lidar com o tipo de interface.

No livro "Effective Java" de Joshua Bloch, o princípio é expresso de forma mais clara, no "Item 52: Consulte objetos por suas interfaces". Ele ainda diz, em letras garrafais:

É inteiramente apropriado para se referir a um objeto por uma classe em vez de um interface se existe nenhuma interface apropriada.

Para o teste de unidade, a situação é completamente dependente das capacidades da ferramenta de zombaria usado. Com a minha própria ferramenta, JMockit , eu posso escrever testes de unidade com a mesma facilidade para o código que interfaces de usos e Dependency Injection como para o código que utiliza classes finais instanciado de dentro do código sob teste.

Então, para mim, a resposta é: sempre usar interfaces que já existem, mas evitar a criação de novas, se não há nenhuma boa razão para fazê-lo (e testability , por si só, não deve ser um).

Escrevendo de interface antes que seja necessário (tanto para testes ou arquitetura) é um exagero.

Além disso, escrevendo uma interface manualmente é um desperdício de tempo. Você pode usar refatoração "Membros puxar" do ReSharper para deixá-lo criar nova interface para fora da classe específica em questão de segundos. Outras ferramentas de refatoração que se integram com IDE deve ter uma funcionalidade semelhante também.

Eu normalmente só usar interfaces em que faz sentido em projetos menores. No entanto, o meu mais recente trabalho tem um grande projeto, onde quase todos os objetos de domínio tem um interface. É provavelmente um exagero e é definitivamente chato, mas a nossa forma de fazer testes e uso da Primavera para injeção de dependência tipo de exija.

Nós principalmente escrever aplicações Web com Wicket, Spring e Hibernate e usar interfaces para Beans Primavera, por exemplo, Serviços e DAOs. Para estas classes, interfaces de fazer totalmente o sentido. Mas também usar interfaces para cada classe de domínio único e acho que isso é apenas um exagero.

Mesmo se você é certeza que não só vai ser um tipo concreto de um objeto de modelo, usando interfaces faz zombando e testar um pouco mais fácil (mas estes dias, há framworks que podem ajudar a gerar classes simuladas automaticamente, mesmo para betão Java classes: Mockito, JTestR, Primavera, Groovy ...)

Mas eu ainda mais frequentemente usar interfaces de serviços, uma vez que é ainda mais importante para zombar-los durante o teste, e programação contra interfaces de ajuda a pensar sobre coisas como encapsulamento.

interfaces de escrita para classes de domínio pode fazer sentido se você estiver usando-o para testes de unidade. Usamos objetos Mock em testes de unidade. Então, se você tem uma interface para um objeto de domínio e seu próprio objeto de domínio não está pronto, mas o cliente pode testar seu uso da interface com a ajuda de objetos mock.

intefaces também testar várias implementações de suas interfaces para o seu modelo de domínio. Então, eu não acho que é sempre um exagero.

Eu acho que a razão principal para a programação contra interfaces é a capacidade de teste. Assim, para os objetos de domínio - se ater apenas ao POJOs ou POC # Os :) etc., ou seja, basta manter suas classes de adicionar qualquer estrutura específica, de modo a impedi-los de differend compilação e tempo de execução dependências e isso é tudo. Criação de interfaces para DAOs é uma boa idéia embora.

Nós extrair as interfaces de tudo só porque ajuda a testar (zombando) e para coisas como AOP. Eclipse pode fazer isso automaticamente. Refactor-> Extract Interface

E se você precisar modificar a classe mais tarde, você pode usar Refactor-> Pull Up ... para puxar para cima os métodos que você precisa para a interface.

* Eu faço isso porque eu preciso dele para a criação de proxies de meus objetos de domínio.

Isso é outra coisa a ter em mente que eu tenho que correr para, especialmente com objetos de domínio e DAO gerados. Muitas das interfaces são muito específico. Dizer um monte de objetos de domínio têm um ID e um campo de status, Por que eles não compartilham uma interface comum? Essa frustração me causou, um plano desnecessariamente modelo de domínio (herança-wise).

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