Qual possui acoplamento menor?

27 respostas
rylphs

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.

27 Respostas

rodrigoy

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.

B

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

Ferryman

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

rylphs

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.

fantomas

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

flws

rylphs

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.

Andre_Brito

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?

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

Fernando_Generoso_da

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

Seguiria, se ClasseX fosse uma interface…

Fernando

fantomas

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

rylphs

Fernando Generoso da Rosa:
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

Seguiria, se ClasseX fosse uma interface…

Fernando

Então o ideal é que eu sempre crie interfaces? Ou só em casos específicos?

C

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.

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

C

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

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.

rylphs

Como assim? Não entendi. :oops:

C

Como assim? Não entendi. :oops:

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

rylphs

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?

Andre_Brito

rylphs,

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

rylphs

Andre Brito:
rylphs,

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

Obrigado, vou dar uma olhada lá!

ramonchiara

Meus 2 cents:

Faltou falar da Lei de Demeter, que está sendo violada…
No caso que você falou abaixo, você está tentando obter os DAOs de outras classes:

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();   
     ...   
   }   
}

Por quê não usar assim:

public Class ClasseY{   
    Dao1 d1;   
    Dao2 d2;   
  
   ClasseY(Dao1 d1, Dao2 d2){   
      this.d1 = d1;   
      this.d2 = d2;   
   }   
  
   public void algumMetodo(){   
     int consulta1 = d1.getAlgumCampo();   
     int consulta2 = d2.getAlgumCampo();   
     ...   
   }   
}

Pronto, você não está mais dependendo da Classe X e sim apenas dos DAOs, que você queria desde o início…
Alguém comentou de IoC / Injeção de Dependência, que é a solução nesse caso…

fantomas

Não é regra geral, como disse antes é apenas um dos princípios da OO.

Neste caso vou lhe indicar este livro:

Use A Cabeça! Padroes De Projetos (em Portugues) (2007)
FREEMAN, ERIC / FREEMAN, ELISABETH
ALTA BOOKS
INFORMATICA

http://www.livrariacultura.com.br/scripts/cultura/busca/busca.asp?palavra=padr%F5es+de+projetos&tipo_pesq=titulo&sid=189859771139516865466146&k5=128D6ADD&uid=&limpa=0&parceiro=OTOXAX&x=0&y=0

Existem outros do genero, vale a pena explorar o assunto.

flws

B

Andre Brito:
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?

Tem razão, nem tinha pensado nas interfaces. Pensei no acoplamento já pensando em diminuir as dependências de sub-sistemas/grupos de classes de outras classes.

Tudo para não virar aquele emanharado de imports no projeto.

rylphs

ramonchiara:
Meus 2 cents:
Faltou falar da Lei de Demeter, que está sendo violada…

Caramba! Quanto mais eu aprendo, mais eu descubro que tem mais coisa pra aprender. O erro do meu código seria o fato de ele estar pedindo a X que lhe entregue os DAO’s? E se se tratasse de uma fábrica?

Acho que confundi alguns conceitos. :oops: Não sei se são realmente DAO’s. São classes mapeadas para o hibernate, acho que se chamam POJO’s. É a mesma coisa?

fantomas:
Neste caso vou lhe indicar este livro:

Use A Cabeça! Padroes De Projetos (em Portugues) (2007)
FREEMAN, ERIC / FREEMAN, ELISABETH
ALTA BOOKS
INFORMATICA

Eu estou lendo o livro padrões de projeto do GOF, mas estou apanhando um pouco pra entender alguns conceitos, principalmente por se tratar de um livro focado em Smalltalk/C++.

Eu estou lendo também “Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and the Unified Process”, mas dei uma parada pra investigar melhor os padrões GOF.

Vejo que tem muito conceito, muita coisa relacionada a OO. Eu tenho pesquisado bastante sobre padrôes. Tem mais algum tipo de leitura que vocês me recomendam? Algo que fale sobre coisas como essa lei do Demeter, talvez.

Muito obrigado galera, vocês estão realmente me ajudando muito! :smiley:

Andre_Brito

Acho que essa “fábrica” seria uma das interfaces. Não sei se o que vou falar é certo, mas seria alguma coisa do tipo ter uma interface DAO geral, com as outras DAOs como subclasse, que vão dizer como pegar os dados (tipo DAODoCliente, que vai pegar os dados do cliente e mandar pra “camada de negócio”).

Além disso, você poderia usar fábrica (ou Factory), pra fazer uma classe geral (quer seria uma interface também) e fazer outras classes Factory criarem os DAOs. Essas fábricas que iriam decidir qual tipo de acesso seria feito (usando XML, banco de objetos, banco relacional e por aí vai).

Acho que não cara. POJO é tipo uma entidade. Uma classe Cliente com nome, telefone, endereço, por exemplo. DAOs são classes onde métodos como acessarPorNome, acessarPorTelefone, acessarPorEndereço vão.

rylphs:
Eu estou lendo o livro padrões de projeto do GOF, mas estou apanhando um pouco pra entender alguns conceitos, principalmente por se tratar de um livro focado em Smalltalk/C++.

Eu estou lendo também “Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and the Unified Process”, mas dei uma parada pra investigar melhor os padrões GOF.


O Head First é mais fácil de ler, mas é complicado viver sem o do GOF. Acho que este último não serve como um textbook, mas sim como um livro de consulta. Já o Head First é mais tranquilo de ler.

Não leve tudo o que falei como “resposta de Deus”. Eu não lidei com isso ainda, então não tenho uma base muito forte pra te dizer.
Abraço.

rylphs

Obrigado André Brito.

Emerson_Macedo

Na verdade faz diferença pois na primeira alternativa da pra fazer um mock pra testar já na segunda não.

Spool

Tem certeza disso? rsrs

Bom, para as classes “chamadoras”, não importa o que o método faz internamente. Porém, a pergunta sobre acoplamento é da classe que implementa o método.
Nesse caso, concordo com a resposta do rodrigoy.

A estrutura ao redor da implementação desse objeto teria que ser muito bem elaborada para que diminuisse o acoplamento.
Repare que eu disse “diminuir”. Em ambas as situações, a dependencia ainda existirá.

Até.

Criado 28 de maio de 2009
Ultima resposta 2 de jun. de 2009
Respostas 27
Participantes 11