Uso interfaces raramente e as acho comuns em outros códigos.
Também crio sub e super classes (ao criar minhas próprias classes) raramente no meu código.
- Isso é uma coisa ruim?
- Você sugeriria mudar esse estilo?
- Esse estilo tem algum efeito colateral?
- Isso é porque não trabalhei em nenhum grande projeto?
programming-practices
coding-style
interfaces
jineesh joseph
fonte
fonte
Respostas:
Há várias razões pelas quais você pode querer usar interfaces:
http://msdn.microsoft.com/en-us/library/3b5b8ezk(v=vs.80).aspx
As interfaces são como qualquer outra coisa na programação. Se você não precisar deles, não os use. Já os vi usados extensivamente por uma questão de estilo, mas se você não precisa das propriedades e dos recursos especiais que uma interface fornece, não vejo o benefício de usá-los "apenas porque".
fonte
A herança de classe e as interfaces têm seu lugar. Herança significa "é um", enquanto uma interface fornece um contrato que define como algo "se comporta".
Eu diria que usar interfaces com mais frequência não é uma prática ruim. Atualmente, estou lendo "C # eficaz - 50 maneiras específicas de melhorar seu c #", de Bill Wagner. O item número 22 declara e cito "Prefiro definir e implementar interfaces à herança".
Geralmente, uso classes base quando preciso definir uma implementação específica de comportamento comum entre tipos conceitualmente relacionados. Mais frequentemente eu uso interfaces. Na verdade, normalmente começo definindo uma interface para uma classe quando começo a criar uma ... mesmo que no final não compile a interface, acho que ajuda começar definindo a API pública do classe desde o início. Se eu achar que tenho várias classes implementando a interface e a lógica de implementação é idêntica, só então me perguntarei se faria sentido ou não implementar uma classe base comum entre os tipos.
Algumas citações do livro de Bill Wagners ...
todas as classes derivadas incorporam imediatamente esse comportamento. Adicionar um membro a uma interface quebra todas as classes que implementam essa interface. Eles não conterão o novo método e não serão mais compilados. Cada implementador deve atualizar esse tipo para incluir o novo membro. Escolher entre uma classe base abstrata e uma interface é uma questão de como apoiar melhor suas abstrações ao longo do tempo. As interfaces são corrigidas: você libera uma interface como um contrato para um conjunto de funcionalidades que qualquer tipo pode implementar. As classes base podem ser estendidas ao longo do tempo. Essas extensões se tornam parte de todas as classes derivadas. Os dois modelos podem ser combinados para reutilizar o código de implementação enquanto suportam várias interfaces ". Eles não conterão o novo método e não serão mais compilados. Cada implementador deve atualizar esse tipo para incluir o novo membro. Escolher entre uma classe base abstrata e uma interface é uma questão de como apoiar melhor suas abstrações ao longo do tempo. As interfaces são corrigidas: você libera uma interface como um contrato para um conjunto de funcionalidades que qualquer tipo pode implementar. As classes base podem ser estendidas ao longo do tempo. Essas extensões se tornam parte de todas as classes derivadas. Os dois modelos podem ser combinados para reutilizar o código de implementação enquanto suportam várias interfaces ". Eles não conterão o novo método e não serão mais compilados. Cada implementador deve atualizar esse tipo para incluir o novo membro. Escolher entre uma classe base abstrata e uma interface é uma questão de como apoiar melhor suas abstrações ao longo do tempo. As interfaces são corrigidas: você libera uma interface como um contrato para um conjunto de funcionalidades que qualquer tipo pode implementar. As classes base podem ser estendidas ao longo do tempo. Essas extensões se tornam parte de todas as classes derivadas. Os dois modelos podem ser combinados para reutilizar o código de implementação enquanto suportam várias interfaces ". Você libera uma interface como um contrato para um conjunto de funcionalidades que qualquer tipo pode implementar. As classes base podem ser estendidas ao longo do tempo. Essas extensões se tornam parte de todas as classes derivadas. Os dois modelos podem ser combinados para reutilizar o código de implementação enquanto suportam várias interfaces ". Você libera uma interface como um contrato para um conjunto de funcionalidades que qualquer tipo pode implementar. As classes base podem ser estendidas ao longo do tempo. Essas extensões se tornam parte de todas as classes derivadas. Os dois modelos podem ser combinados para reutilizar o código de implementação enquanto suportam várias interfaces ".
"As interfaces de codificação fornecem maior flexibilidade a outros desenvolvedores do que a codificação para tipos de classe base".
"O uso de interfaces para definir APIs para uma classe fornece maior flexibilidade."
"Quando seu tipo expõe propriedades como tipos de classe, expõe toda a interface a essa classe. Usando interfaces, você pode optar por expor apenas os métodos e propriedades que deseja que os clientes usem."
"As classes base descrevem e implementam comportamentos comuns entre tipos de concreto relacionados. As interfaces descrevem peças atômicas de funcionalidade que tipos de concreto não relacionados podem implementar. Ambas têm seu lugar. As classes definem os tipos que você cria. As interfaces descrevem o comportamento desses tipos como peças de funcionalidade. Se você entender as diferenças, criará designs mais expressivos e mais resilientes diante da mudança. Use hierarquias de classes para definir tipos relacionados. Exponha a funcionalidade usando interfaces implementadas nesses tipos ".
fonte
Uma coisa que não foi mencionada é o teste: em todas as bibliotecas de simulação do C #, bem como em Java, as classes não podem ser ridicularizadas, a menos que implementem uma interface. Isso leva muitos projetos a seguir as práticas Agile / TDD para dar a cada classe sua própria interface.
Algumas pessoas consideram essa prática recomendada, porque "reduz o acoplamento", mas eu discordo - acho que é apenas uma solução alternativa para uma deficiência no idioma.
Eu acho que as interfaces são melhor usadas quando você tem duas ou mais classes que, abstratamente, fazem a "mesma coisa", mas de maneiras diferentes.
Por exemplo, a estrutura .Net possui várias classes que armazenam listas de coisas , mas todas elas armazenam essas coisas de maneiras diferentes. Portanto, faz sentido ter uma
IList<T>
interface abstrata , que pode ser implementada usando métodos diferentes.Você também deve usá-lo quando quiser que duas ou mais classes sejam intercambiáveis ou substituíveis no futuro. Se uma nova maneira de armazenar listas for lançada no futuro,
AwesomeList<T>
supondo que você tenha usadoIList<T>
todo o seu código, alterá-lo para usoAwesomeList<T>
significaria apenas alterar algumas dezenas de linhas, em vez de algumas centenas / mil.fonte
O principal resultado de não usar herança e interfaces quando elas são apropriadas é o acoplamento rígido . Isso pode ser um pouco difícil de aprender a reconhecer, mas geralmente o sintoma mais óbvio é que quando você faz uma alteração, muitas vezes precisa passar por vários outros arquivos para fazer alterações em um efeito cascata.
fonte
Não, isso não é ruim. Interfaces explícitas devem ser usadas, se e somente se, duas classes com uma interface comum precisam ser intercambiáveis em tempo de execução. Se eles não precisam ser intercambiáveis, não os herdam. É simples assim. A herança é frágil e deve ser evitada sempre que possível. Se você puder evitá-lo ou usar genéricos, faça isso.
O problema é que, em linguagens como C # e Java com genéricos fracos em tempo de compilação, você pode acabar violando o DRY porque não há como escrever um método que possa lidar com mais de uma classe, a menos que todas as classes sejam herdadas da mesma base. C # 4
dynamic
pode lidar com isso, no entanto.O problema é que a herança é como variáveis globais - uma vez que você o adiciona e seu código depende, Deus o ajude a removê-lo. No entanto, você pode adicioná-lo a qualquer momento e até mesmo sem alterar a classe base usando um tipo de wrapper.
fonte
Sim, não (ou muito raramente) o uso de interfaces é provavelmente uma coisa ruim. As interfaces (no sentido abstrato e a construção da linguagem C # / Java são uma boa aproximação desse sentido abstrato) definem pontos de interação explícitos entre sistemas e subsistemas. Isso ajuda a reduzir o acoplamento e torna o sistema mais sustentável. Como qualquer coisa que melhore a capacidade de manutenção, torna-se mais importante quanto maior o sistema.
fonte
Eu não uso uma interface há anos. Claro que isso é porque eu tenho programado quase exclusivamente em Erlang há anos e todo o conceito de interface simplesmente não existe. (O mais próximo que você chega é de um "comportamento" e isso não é a mesma coisa, a menos que você olhe com força e olhe para eles pelo canto do olho.)
Então, realmente, sua pergunta depende do paradigma (OOP neste caso) e, além disso, é realmente muito dependente da linguagem (existem linguagens OOP sem interfaces).
fonte
Se você está falando sobre o uso de Java, uma razão para o uso de interfaces é que elas permitem o uso de objetos proxy sem bibliotecas de geração de código. Isso pode ser uma vantagem substancial quando você estiver trabalhando com uma estrutura complexa como o Spring. Além disso, algumas funcionalidades requerem interfaces: o RMI é o exemplo clássico disso, pois é necessário descrever a funcionalidade que você está fornecendo em termos de interfaces (que são herdadas
java.rmi.Remote
), independentemente da implementação.fonte
As coisas estão mudando ( MS Moles ), mas a principal razão pela qual acho bom codificar quase exclusivamente para interfaces é que elas são fáceis de zombar e se encaixam naturalmente em uma arquitetura de IoC.
Na IMO, você só deve trabalhar com interfaces ou DAOs completamente burros, sempre que possível. Quando você entra nessa mentalidade e começa a usar uma biblioteca que não se expõe por meio de interfaces e faz tudo por meio de objetos concretos, eu tenho que ser honesto, tudo parece um pouco desajeitado.
fonte
Para projetos de moda antiga, utiliza-se interfaces para evitar referências circulares, porque as referências circulares podem se tornar um grande problema de manutenção a longo prazo.
Ruim:
Não é ruim:
Geralmente A, B, PartOfClassB_AccessedByA implementado com arquivos separados.
fonte
A programação baseada em interface ajuda a tornar o código mais flexível e fácil de testar. As classes de implementação podem ser alteradas sem tocar no código do cliente [Flexibilidade]. Ao testar o código, pode-se substituir a programação baseada na interface real, ajudando a tornar o código mais flexível e fácil de testar. As classes de implementação podem ser alteradas sem tocar no código do cliente [Flexibilidade]. Durante o teste do código, é possível substituir o objeto real por objetos simulados [Testability] .bject por objetos simulados [Testability].
fonte