Qual possui acoplamento menor?

27 respostas
R

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

R

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

F

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

R

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.

F

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

flws

R

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.

A

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?

F

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

F

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

F

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

R

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.

R

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.

R

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

R

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?

A

rylphs,

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

R

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á!

R

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…

F

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.

R

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:

A

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.

R

Obrigado André Brito.

E

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

S

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