Não tem muita relação com acoplamento. Nas duas alternativas a classe está dependendo da Classe X. Se a classe X é abstrata, aí sim a alternativa 1 é menos acoplada. Se não é, tanto faz…
Para falar a verdade, na alternativa 2 você está com uma dependência maior com relação à criação do objeto, mas, como disse, a dependência existe nas duas opções.
A primeira a opção possui menor acoplamento, pois o método “algumaCoisa(ClasseX x)” não sabe como criar uma instancia da ClasseX. Seria possível criar por exemplo um subtipo da ClasseX e passar como parâmetro para o método “algumaCoisa(ClasseX x)”. Essa pode ser uma boa pratica para fazer testes unitários por exemplo, isolando o Objeto que está sendo testado de suas dependências.
O acoplamento então seria o mesmo? O primeiro o método é mais independente da classe X não é? Primeiro porque não precisa saber como a classe é criada, e segundo porque posso alterar a classe X chamada somente chamando o método com outro parâmetro, desde que a classe que eu passe por parâmetro tenha a mesma interface de X. Estou no caminho certo?
Mesmo compreendendo o conceito de acoplamento, às vezes acho difícil mensurar isso na prática e decidir o melhor caminho pra diminuir o mesmo. No link http://en.wikipedia.org/wiki/Coupling_(computer_science) tem uma fórmula pra calcular o acoplamento, mas não consegui identificar perfeitamente cada tipo de acoplamento.
Entendi. Mas mesmo assim o primeiro caso ainda seria melhor, não é? A dúvida surgiu quando eu estava analisando uma classe de um programa que eu e amigos meus estamos desenvolvendo. A gente criou um singleton que permite acesso a alguns DAO’s. Algo como isso:
public void algumMetodo(){
int consulta1 = Singleton.getInstance().getDao1().getAlgumCampo();
int consulta2 = Singleton.getInstance().getDao2().getAlgumCampo();
}
Eu não gostei, e sugeri que fosse usado algo como:
public void algumMetodo(ClasseX x){
int consulta1 = x.getDao1().getAlgumCampo();
int consulta2 = x.getDao2().getAlgumCampo();
...
}
No segundo caso tiraria até a necessidade da classe ser singleton. Ela ficaria visível somente a uma classe que a passaria por parâmetro quando chamasse o método. Funcionaria como uma fábrica?
Eu pensei também na possibilidade de colocar os DAOs que eu vou utilizar como atributos, e eu passaria “x” no construtor da classe que obteria os DAOs, mais ou menos assim:
public Class ClasseY{
Dao1 d1;
Dao2 d2;
ClasseY(ClasseX x){
d1 = x.getDao1();
d2 = x.getDao2();
}
public void algumMetodo(){
int consulta1 = d1.getAlgumCampo();
int consulta2 = d2.getAlgumCampo();
...
}
}
Bem, me desculpem por tantas dúvidas, mas é que ainda estou muito cru com relação a OO, padrões, e com relação a java, e muitas dúvidas aparecem. O que vocês acham? Talvez tenham até outra sugestão. Me desculpem também por passar algo muito abstrato, mas não lembro direito do código.
Bruno Laturner,
Achei bem colocado o que você disse. Só que o acoplamento, nesse caso, vai existir sempre “do nível de classe”. Então acho que teria mais alguma classe envolvida aí (algo como Façade (não tenho certeza)).
Programar para interface e não para implementação é um dos princípios da OO.
E para suportar essa idéia segue estes itens:
a) O objeto cliente fica independente da implementação do objeto que lhe serve.
b) O objeto que implementa uma interface pode ser facilmente substituido por outro, mesmo dinamicamente.
c) Tem baixo acoplamento.
d) Aumenta as chances de reuso.
e) Aumenta a possibilidade do uso da composição pelo fato de vc poder utilizar vários objetos diferentes mas do mesmo tipo (interface).
[quote=Fernando Generoso da Rosa][quote=Ferryman]O primeiro exemplo segue a idéia de IoC, da uma lida aqui que você vai entender porque o acoplamento é menor. http://en.wikipedia.org/wiki/Inversion_of_Control
[]s[/quote]
Seguiria, se ClasseX fosse uma interface…
Fernando
[/quote]
Então o ideal é que eu sempre crie interfaces? Ou só em casos específicos?
Isso foi só um exemplo mais curto. A questão é o que eu devo fazer quando me deparar com esse tipo de situação. Devo criar o objeto dentro da classe, delegar a criação à quem irá chamar o método, ou talvez isso dependa da situação? Gostaria de saber também sobre o uso de interfaces. Sempre devo criar interfaces? É isso que significa “Programe para uma interface, e não para uma classe”?
Mais uma vez, me desculpem por tantas perguntas, mas ainda tenho muito o que aprender.
[quote=rylphs]
Isso foi só um exemplo mais curto. A questão é o que eu devo fazer quando me deparar com esse tipo de situação. Devo criar o objeto dentro da classe, delegar a criação à quem irá chamar o método, ou talvez isso dependa da situação? Gostaria de saber também sobre o uso de interfaces. Sempre devo criar interfaces? É isso que significa “Programe para uma interface, e não para uma classe”?
Mais uma vez, me desculpem por tantas perguntas, mas ainda tenho muito o que aprender.
Obrigado[/quote]
O exemplo é curto mas serve pra mostrar uma pratica que é muito comum. E quando se deparar com ela deve refatorar para melhor expressar a intencao do codigo. Em se tratando de objetos, alterar os parametros de uma funcao é considerado programacao de risco, voce nao esta reduzindo acoplamento, e sim o contrario.
Baseado no seu exemplo, sim, delegar a criacao do objeto para quem ira chamar o metodo teria um menor acoplamento.
fantomas, isso quer dizer que sempre devo criar interfaces e então implementá-las no lugar de apenas criar classes? Isso é uma regra geral, ou específica desse caso?