Qual possui acoplamento menor?

Será que alguém poderia tirar uma dúvida minha?
Em qual das duas situações eu tenho um acoplemento menor?

Nessa?

public void algumaCoisa(ClasseX x){
   x.facaAlgo();
}

Ou nessa?

public void algumaCoisa(){
  ClasseX x = new ClasseX();
  x.facaAlgo();
}

Eu acho que a primeira forma é melhor, não é? Que tipos de acoplamento eu tenho nos dois casos?

Obrigado.

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.

No segundo é menor o acoplamento pois as classes que chamam o método não precisam saber da existência de ClasseX

Descordo,

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.

[]s

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.

Na minha opinião sem usar interfaces ou classes abstratas seu acoplamento sempre será visto como alto.

flws

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.

Ah, e obrigado pelas respostas.

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)).

Fantomas, pode explicar melhor isso?

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=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

Sim…

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).

flws

[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?

O primeiro exemplo dói até na espinha. Chamar um método void num objeto recebido como parâmetro no mínimo é sinal que o design tem que melhorar.

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=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.

Como assim? Não entendi. :oops:

Como assim? Não entendi. :oops:[/quote]

O metodo algumaCoisa() esta alterando o objeto passado como parametro (x.facaAlgo()).

Ah, entendi! Obrigado.

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?

rylphs,

Acho que a discussão que acontece nesse tópico é bem legal e dá pra tirar alguma conclusão.

[quote=Andre Brito]rylphs,

Acho que a discussão que acontece nesse tópico é bem legal e dá pra tirar alguma conclusão.[/quote]

Obrigado, vou dar uma olhada lá!