OOP: Quais são algumas das situações em que o design baseado em classe é melhor que o baseado em interface?

9

Eu estava lendo o site do JDOM .

Por que a API JDOM é definida em termos de classes concretas em vez de interfaces?

Jason Hunter resume os argumentos em relação a uma API baseada em interface para JDOM:

Com as interfaces, tudo se torna uma fábrica, os elementos precisam ser 'importados' para novos documentos, em vez de apenas adicionados, recursos como serialização de longo prazo não podem ser garantidos e a lista continua.

Começamos com interfaces, na verdade. Durante nossa revisão de pré-lançamento para alguns colegas, recebemos o feedback de que deveríamos tentar aulas concretas. Fizemos, e o design foi muito melhor para isso.

Eu sou um designer iniciante. Todo o conselho que ouvi até agora é contra o uso do design com classes concretas.

Pode estar usando classes concretas são apropriadas em determinados lugares. Existem problemas de classe comuns para os quais o uso de classes concretas no design é bom?

Vinoth Kumar CM
fonte
Você pode querer dar uma olhada nisso: javaworld.com/javaworld/jw-09-2001/jw-0921-interface.html
NoChance
Você também pode conferir a série "Limite suas abstrações": ayende.com/blog/153889/…
henginy
"Sim, e o design foi muito melhor para isso". - como foi melhor?
CodeART

Respostas:

5
  • A herança cria dependências na implementação , o que pode ser um grande problema em termos de manutenção. O corolário disso é que você pode usar com segurança classes de herança e concretas ao lidar com objetos de transferência de dados , que por definição quase não contêm implementação. Você também pode usar a herança de classes concretas quando desejar essa dependência. Você pode querer usar uma classe abstrata que contenha os métodos comuns (geralmente funções utilitárias) na parte superior da hierarquia nessa situação.
  • Ao usar uma hierarquia de classes concreta, não se esqueça de aplicar o Princípio de Substituição de Liskov .
  • Não há problema em usar classes concretas para clientes (ou seja, classes que usam, não classes que são usadas).
  • IMHO você pode usar aulas concretas até que haja coisas para mudar. O Princípio Aberto / Fechado diria para você usar interfaces para evitar o acoplamento, mas com relação ao Princípio Você não precisará, você pode considerar o uso de classes concretas até o momento em que precisar alterar algo na implementação. O problema é que você precisaria alterar todos os clientes de suas classes na primeira vez que algo mudar em algum lugar. Embora você tenha apenas uma ferramenta possível para fazer alguma coisa, você pode usar as classes concretas IMO.

[EDIT] O site do JDOM usa java.io.File como exemplo, mas esse é definitivamente um design baseado em interface, pois é possível manipular uma instância de java.io.File como se fosse apenas um serializável. Nesta situação, apenas "criadores" conheceriam a classe concreta

Matthias Jouan
fonte
Existem duas definições conflitantes de "objeto de valor" flutuando. O seu parece ser o menos comum, também conhecido como "objeto de transferência de dados".
Michael Borgwardt
@MichaelBorgwardt Thx para apontar isto como eu não quis dizer "objeto de transferência de dados" apenas: eu editar minha resposta
Matthias Jouan
11
O LSP é importante para qualquer relacionamento de subtipagem, implementação de interface e herança.
2

No site do JDOM:

Jason (Hunter) fundou o projeto JDOM no início de 2000, juntamente com Brett McLaughlin

Ou seja, na época em que o Java 1.3 estava sendo introduzido. Não havia nada em termos de maturidade quando se tratava de desenvolvimento Java - os desenvolvedores mais experientes tinham apenas 4 anos usando Java na melhor das hipóteses. Não havia recipientes de IoC amplamente utilizados, nem Hibernate. O Apache Struts estava apenas começando.

O que é tudo para dizer que Jason e Brett estavam errados. Muitas pessoas ainda não "entenderam". Se eles tinham experiência em C ++, bem, você não precisava de interfaces em C ++ (bem, elas estavam lá em C ++, mas você realmente não precisava delas, certo?), Por que diabos as usa em Java? Bem, há muitas boas razões, para as quais outras pessoas podem direcioná-lo.

Eles estavam definitivamente errados sobre

tudo o que pode ser feito com interfaces pode ser feito com subclassificação

Java não permite herança múltipla de classes, mas permite a implementação de múltiplas interfaces. Isso pode fazer uma diferença real.

Matthew Flynn
fonte
2

Lembre-se, primeiro, que no Desenvolvimento de software existem várias maneiras de resolver um problema e, se algum desenvolvedor usa uma técnica diferente da sua, isso não significa que está errado.

Um desses casos é "interfaces" versus "base" "classes". Há situações em que o mesmo objetivo pode ser alcançado com as duas técnicas.

Para tornar as coisas mais complicadas, existem vários usos de interfaces, apenas para mencionar:

  • um é projetar um "contrato" ou "especificação" sem "implementação"
  • outro para adicionar funcionalidade a uma classe ou hierarquia de classes existente
  • complementar ao anterior, para permitir o acesso compartilhado entre diferentes objetos, tecnologias, por exemplo: Enterprise Beans, CORBA, COM, WebServices
  • emular herança múltipla

Sua pergunta se aplica ao primeiro ponto.

Quando você deseja desenvolver uma hierarquia de classes, não apenas uma única classe, e várias classes pretendem compartilhar alguns recursos específicos, você pode começar com uma classe base, mesmo que isso possa ser feito com uma interface.

E deixe interfaces para os outros cenários.

Um bom exemplo são bibliotecas de widgets (controles).

Eu sugiro que dê uma olhada em outras linguagens de programação, como elas usam interfaces e classes como: PHP, Delphi (Object Pascal), C #.

Felicidades.

umlcat
fonte
0

Você geralmente deseja uma interface para qualquer coisa que seja passada como parâmetro ou retornada, essencialmente para poder dissociar a classe de suas dependências.

Portanto, se estamos procurando uma aula, nunca repassamos normalmente exceções que vêm à mente. Não sou desenvolvedor de Java, mas certamente em outras linguagens semelhantes não acho que vi interfaces definidas por exceções.

jk.
fonte
0

As regras de design da API são realmente uma coisa específica. Não tenho certeza se você deve concluir alguma coisa dessas perguntas frequentes em termos de como deve criar seu código diário.

Para o seu código regular, ainda é verdade que você usará a herança de interface ou classe abstrata com muito mais frequência do que o IMO de herança de baunilha.

Para entender bem essa regra, você deve se colocar não do ponto de vista de uma classe derivada versus sua superclasse, mas do ponto de vista de um objeto que depende de outro objeto. É quase sempre melhor depender de uma abstração do que de uma implementação concreta, pois permite que você aceite uma série inteira de classes diferentes como dependências, confiando no contrato e não nos detalhes da implementação.

O primeiro uso para isso é muitas vezes em testes de unidade - se você realmente quer unidade de teste de sua classe em completo isolamento, você faz isso contra falsos implementações de suas dependências que são diferentes das implementações reais que serão utilizados na produção.

guillaume31
fonte