Programar para Interfaces

Amigos(as),

Estou montando um texto e gostaria saber se algum de vocês sabem qual foi o primeiro autor e qual foi a obra que constou o princípio “programe para uma interface, não para uma implementação”.

Isso aparece em tudo quanto é lugar, mas gostaria saber se existe uma referência bibliográfica… “o dono da idéia”. Capiche?

Abraços!

Olá

Sem a pretensão de esgotar o assunto…

O conceito básico é:
“Favor object composition over class inheritance.”

A primeira aparição dele foi no livro do GoF há mais de 10 anos atrás.

O pattern Strategy do GoF já pode ser considerado como um exemplo do conceito “program to an interface, not an implementation”

A ênfase na composição, vi depois já adaptado para o Java no livro do Peter Coad, Java Design de 1997.

Este conceito chama a atenção para o uso inadequado da herança.

Mais recentemente grandes autores de livros de Java como Joshua Bloch erm Effective Java (capítulo 4) e depois Rod Johnson em J2EE Design and Developmentt (capítulo 4, resumo na pag. 115) enfatizaram as vantagens de programar para interfaces e não para classes.

Quando pesquisar para preparar suas aulas, dê uma olhada em:
http://www.netobjectives.com/resources/rs_bks.htm

[]s
Luca

Luca,

“programar para uma interface” é explorar o polimorfismo permitindo que o objeto em runtime mude.

“preferir composição à herança” está mais relacionado com algumas inflexibilidades da herança que podem minar a evolução do software…

São princípios diferentes…

Olá

Minha resposta deve ter ficado confusa porque editei várias vezes pois fazia trocentas coisas ao mesmo tempo e foi difícil manter a linha de raciocínio.

Porém, o principal que fale é isto mesmo:

Preferir composição à herança é historicamente a primeira manifestação de programar para interfaces. E o que você pediu foi a história.

Sua definição de programar para interface é puramente teórica. Na prática quando você listar as vantagens deste conceito vai encontrar a definição do GoF escrita pensando em C++ ou Smaltalk.

[]s
Luca

Acho que uma coisa não tem muito a ver com a outra trocando em miudos voce pode programar para a inteface de uma classe pai e utilizar uma classe filha em run time. Por tanto a herança não prejudica a programação para interface.

Preferir composição à herança é muito mencionado pois pessoas utilizam herança para implementar o conceito de papel que é uma forma ruim de se implementar papel.

Ao meu ver programar para interface surgiu para ajudar as pessoas programar de forma melhor com encapsulamento não só para se utilizar de polimorfismo.

O maior beneficio de se programar para interface é controlar o efeito colateral de alterações, ou seja utilizar encapsulamento!

Na verdade tem muitos benefícios até quando você utiliza abstração vc programa para interface…

O conceito tem raiz em coisas do inicio da década de 80, quando se falava muito em programar no smalltalk contra o contrato de uma classe, não o tipo dela.

Interfaces são uma forma limitada do mecanismo de contratos que o smalltalk tem.

Mas na UML é melhor representar muitos papéis de uma classe usando herança mesmo ?
Ou usar a composição.
Digo isso pois estou tentando seguir a linha da abstração da UML.

[quote=okara]Mas na UML é melhor representar muitos papéis de uma classe usando herança mesmo ?
Ou usar a composição.
Digo isso pois estou tentando seguir a linha da abstração da UML.
[/quote]

A solução que você vai dar na UML deve ser a mesma que você vai implementar no código. A abstração é a mesma. Não é uma boa idéia trabalhar muito abstratamente na UML ao ponto do código ser completamente diferente.

O que você deve ter em mente é que, se você for tratar todas as variâncias com herança, seu modelo ficará complexo e inflexível. Entre seus papéis, analise o que varia, e veja se a aplicação de um Strategy ou um Decorator ou outros patterns não deixariam seu modelo mais flexível. De qualquer forma, uma simples herança já resolve alguns casos sem comprometer o modelo.

Eu fico confuso desse jeito.
Se eu for colocar no diagrama tudo que tem na implementação, o modelo não vai ficar poluído ?

Estou construindo um diagrama de classes, mas não quero colocar recursos de Log no modelo por exemplo.
Isso não é relevante para meu modelo de domínio.

E não é mais fácil visualizar diferentes papéis por exemplo da class pessoa com uma notação de herança ao invés de uma composição ?

[quote=okara]Eu fico confuso desse jeito.
Se eu for colocar no diagrama tudo que tem na implementação, o modelo não vai ficar poluído ?

Estou construindo um diagrama de classes, mas não quero colocar recursos de Log no modelo por exemplo.
Isso não é relevante para meu modelo de domínio.
[/quote]

Peraí, não falei para colocar tudo no modelo UML, se vc está usando um modelo de domínio, só este estaria no modelo UML, a infra fica fora…

Se você tem uma classe Pessoa no diagrama UML é esperado que você tenha uma classe Pessoa no seu código segundo o diagrama.

[quote=okara]E não é mais fácil visualizar diferentes papéis por exemplo da class pessoa com uma notação de herança ao invés de uma composição ?
[/quote]

Para você usar a composição no lugar da herança é necessário aplicar Patterns. Se decidir usar Strategy, use-o no modelo UML e no código. Se decidir por usar herança, use-a no modelo UML e no código. O que eu quero falar é que usar herança no modelo UML e Strategy no código tornam as coisas confusas…