Você está na página 1de 14

Acoplamento e Coeso

Acoplamento uma medida inter componentes. Isto , uma medida entre


componentes de um conjunto. No caso de um sistema uma medida do
relacionamento entre subsistemas. No caso de um programa composto de funes,
uma medida do relacionamento entre funes. Os dois espectros dessa medida: so
alto acoplamento e baixo acoplamento. Componentes que tm baixo ou fraco
acoplamento so considerados mais independentes um do outro. O inverso vale para
alto ou forte acoplamento.
Coeso uma medida intra componentes. Isto , procura medir um componente
individualmente. No caso de um sistema, mede-se a coeso de cada sub-sistema. No
caso de um programa organizado por funes, mede-se a coeso de cada funo. A
coeso pode ser alta ou baixa. Obter coeso alta imprescindvel em todo sistema
bem organizado. Entende-se coeso alta, quando os integrantes de um componente
esto relacionados a um tema comum, isto tem o mesmo objetivo, fazem uma nica
coisa. A coeso alta tambm conhecida como coeso funcional. Um bom indicativo
de componentes com baixa coeso o ttulo ou nome do componente: todo
componente que se utiliza do conector e ou do conector ou um forte candidato para
ser classificado como tendo baixa coeso. Veja que o ttulo dessa nota
(propositalmente) apresenta uma baixa coeso.
O conceito de organizao modular fundamental em Teoria Geral de Sistemas, por
um motivo bvio: um sistema sempre um subsistema de um sistema mais abstrato,
ou de nvel hierrquico mais alto, representando-se a idia da decomposio como
uma hierarquia. Usa-se o termo modularidade para refletir a propriedade de algo ter
uma organizao modular. Veja que usei o termo subsistema, mas poderia ter utilizado
o termo sub-mdulo.

Organizao Modular
A organizao modular tem como finalidade bsica auxiliar o gerenciamento de
sistemas complexos.
Creio que um bom resumo sobre organizao modular texto inicial do Captulo 3 e
do Captulo 4 do livro de Abelson, Sussman and Sussman. Cito algumas partes
desses dois textos a seguir: a) A Sntese efetiva de programas tambm precisa de
princpios organizacionais que nos guie na formulao do desenho de um programa.
Em particular, precisamos de estratgias para nos ajudar a estruturar grandes
sistemas de tal maneira que eles tenham uma organizao modular, isto que eles
possam ser divididos naturalmente em partes coerentes que possam ser
separadamente desenvolvidas e mantidas e b) Em nosso estudo de desenho de
programas, nos vimos que especialistas controlam a complexidade de seus desenhos
usando tcnicas gerais usadas por desenhistas de todos os sistemas complexos. Eles

combinam elementos primitivos para formar objetos compostos, eles abstraem objetos
compostos para formar blocos de construo de alto-nvel, e eles preservam a
modularidade atravs da adoo de vises de larga escala para a estrutura do
sistema.
No tratado de Teoria Geral de Sistemas, Bertallanfy escreve na pgina 55 que o ditado
O todo maior que a soma das partes na verdade o fato de que as caractersticas
constitutivas no so explicadas a partir das caractersticas das partes isoladas, mas a
partir dessas partes e das suas relaes.
No entanto, fica no ar a questo de como identificar mdulos, como fracionar um todo?
A idia de que forma segue funo uma das mais importantes heursticas para
organizar de forma modular. O livro de Abelson, Sussman e Sussman, no incio do
Capitulo 3 menciona explicitamente essa estratgia.
No entanto, como saber se nosso todo est bem organizado modularmente. Ou seja,
como qualificar o resultado de termos organizado o sistema de maneira modular. Qual
a modularidade desse sistema?
Em sistemas que precisam ter independncia entre suas partes para facilitar sua
evoluo comum adotar-se a estratgia de mdulos com forte independncia de
outros mdulos e com forte unicidade. Isso caracteriza sistemas onde o acoplamento
entre sub-sistemas fraco e onde cada sub-sistema fortemente coeso.
Em engenharia de software, principalmente nos escritos de Constantine e Yourdon as
noes de acoplamento e coeso foram definidas de maneira clara, mas sem um
formalismo adjacente. Essas noes foram herdadas dos conceitos de organizao da
teoria geral de sistemas e da ciberntica.
Alm do trabalho de Constantine e Yourdon importantssimo o trabalho do Prof.
Parnas, que tambm tem relao com a teoria geral de sistemas. Alm de ressaltar a
idia de independncia de mdulos no sentido tanto de coeso e acoplamento, coube
a Parnas criar um conceito sobre o compartilhamento de informao que se tornou um
dos conceitos gerais mais citados na literatura de software. Refiro-me ao conceito de
information hiding ou de proteo da informao. Esse conceito prega que cada
mdulo ou sub-sistema deve guardar para si as informaes que s a ele interessa.
claro, que o conceito, ao ser aplicado a sistemas, gera como efeito um acoplamento
fraco, em funo da heurstica de minimizar o conhecimento compartilhado.
No mundo de orientao a objetos o conceito de acoplamento ficou um tanto confuso.
Vrios autores definem mtricas de acoplamento como sendo uma enumerao de
quantas relaes existem entre as partes e no observam que o fundamental no o
nmero de relaes que um objeto possui, mas sim a qualidade dessa relao. Aqui,
qualidade entende-se pelo quanto cada objeto se deixa conhecer pelo outro. No
entanto, o fato de que a orientao a objetos mistura taxonomia com mereologia1
dificulta a aplicao do conceito de acoplamento fraco.

(Lgica) teoria ou estudo lgico-matemtico das relaes entre as partes e o todo e das
relaes entre as partes no interior de um todo.

Existem mtricas que procuram medir acoplamento e coeso, mas mtricas sobre
proteo de informao so raras e menos utilizadas.

importante ressaltar que o acoplamento forte pode algumas vezes ser necessrio.
Um exemplo onde o acoplamento forte positivo no emprego em engenharia de
produo do conceito de produo just in time. Em alguns casos essa forte
dependncia entre produtores e fornecedores justificada pela reduo de custos. Em
software, muitas vezes um compartilhamento de memria comum plenamente
justificvel em algumas situaes, caracterizando um acoplamento forte entre os
componentes que dividem esse recurso.
Uma heurstica fundamental: o uso do conector e ou ou em um ttulo de um mdulo
(ou subsistema) um forte indicativo da falta de coeso!

Baixo Acoplamento
Problema
Como minimizar dependncias e maximizar o reuso? O acoplamento uma medida de
quo fortemente uma classe est conectada, possui conhecimento ou depende de
outra classe. Com fraco acoplamento, uma classe no dependente de muitas outras
classes. Com uma classe possuindo forte acoplamento, temos os seguintes
problemas:

Mudanas em uma classe relacionada fora mudanas locais classe


A classe mais difcil de entender isoladamente
A classe mais difcil de ser reusada, j que depende da presena de outras
classes

Soluo
Atribuir responsabilidades de forma a minimizar o acoplamento

Exemplo
Considere o seguinte diagrama parcial de classes no estudo de caso:

Suponha que temos que criar um Pagamento e associ-lo a uma Venda


Que classe deveria ter essa responsabilidade?

Alternativa 1: No mundo real, um TPDV "registra" um pagamento e o padro Creator


sugere que TPDV poderia criar Pagamento. TPDV deve ento passar o pagamento
para a Venda.
Veja o resultado abaixo:

Alternativa 2: Criar o Pagamento com Venda e associ-lo Venda


Veja o resultado abaixo

Supondo que a Venda deva ter conhecimento do pagamento (depois da criao) de


qualquer jeito, a alternativa 2 tem menos acoplamento (TPDV no est acoplado a
Pagamento). Dois padres (Creator e Low Coupling) sugeriram diferentes solues.
Minimizar acoplamento ganha

Discusso
Minimizar acoplamento um dos princpios de ouro do projeto OO.
Acoplamento se manifesta de vrias formas:

X tem um atributo que referencia uma instncia de Y


X tem um mtodo que referencia uma instncia de Y
Pode ser parmetro, varivel local, objeto retornado pelo mtodo
X uma subclasse direta ou indireta de Y
X implementa a interface Y

A herana um tipo de acoplamento particularmente forte.


No se deve minimizar acoplamento criando alguns poucos objetos monstruosos (God
classes). Exemplo: todo o comportamento numa classe e outras classes usadas como
depsitos passivos de informao
Tipos de acoplamentos (do menos ruim at o pior):

Acoplamento de dados

Acoplamento de controle
Acoplamento de dados globais
Acoplamento de dados internos

Acoplamento de dados
Situaes:

Sada de um objeto entrada de outro


Uso de parmetros para passar itens entre mtodos

Ocorrncia comum:

Objeto a passa objeto x para objeto b


Objeto x e b esto acoplados
Uma mudana na interface de x pode implicar em mudanas a b

Exemplo:
class Servidor {
public void mensagem(MeuTipo x) {
// cdigo aqui
x.faaAlgo(Object dados); // dados e x esto acoplados
// (se interface de dados mudar x ter que mudar)
// mais cdigo
}
}
Exemplo pior:

Objeto a passa objeto x para objeto b


x um objeto composto ou agregado (contm outro(s) objeto(s))
Objeto b deve extrair objeto y de dentro de x
H acoplamento entre b, x, representao interna de x, y
Exemplo: ordenao de registros de alunos por matrcula
class Aluno {
String nome;
long matrcula;
public String getNome() { return nome; }
public long getMatrcula() { return matrcula; }
// etc.
}
ListaOrdenada listaDeAlunos = new ListaOrdenada();
listaDeAlunos.add(new Aluno(...));
//etc.

Agora, vamos ver os problemas:

class ListaOrdenada {
Object[] elementosOrdenados = new Object[tamanhoAdequado];
public void add(Aluno x) {
// h cdigo no mostrado aqui
long matrcula1 = x.getMatrcula();
long matrcula2 = elementosOrdenados[k].getMatrcula();
if(matrcula1 < matrcula2) {
// faa algo
} else {
// faa outra coisa
}
}
O problema da soluo anterior que h forte acoplamento

ListaOrdenada sabe muita coisa de Aluno


O fato de que a comparao de alunos feito com a matrcula
O fato de que a matrcula obtida com getMatrcula()
O fato de que matrculas so long (representao de dados)
Como comparar matrculas (com <)
O que ocorre se mudarmos qualquer uma dessas coisas?

Soluo 2: mande uma mensagem para o prprio objeto se comparar com outro
class ListaOrdenada {
Object[] elementosOrdenados = new Object[tamanhoAdequado];
public void add(Aluno x) {
// cdigo no mostrado
if(x.compareTo(elementosOrdenados[K]) < 0) {
// faa algo
} else {
// faa outra coisa
}
}
Reduzimos o acoplamento escondendo informao atrs de um mtodo
Problema: ListaOrdenada s funciona com Aluno
Soluo 3: use interfaces para desacoplar mais ainda
interface Comparable {
public int compareTo(Object outro);
}
class Aluno implements Comparable {
public int compareTo(Object outro) {
// compare registro de aluno com outro

// retorna valor < 0, 0, ou > 0 dependendo da comparao


}
}
class ListaOrdenada {
Object[] elementosOrdenados = new Object[tamanhoAdequado];
public void add(Comparable x) {
// cdigo no mostrado
if(x.compareTo(elementosOrdenados[K]) < 0) {
// faa algo
} else {
// faa outra coisa
}
}
Em C++, teria outras solues possveis:

Apontador de funo
Apontador de funo com tipos genricos (templates)

Acoplamento de controle
Passar flags de controle entre objetos de forma que um objeto controle as etapas de
processamento de outro objeto
Ocorrncia comum:

Objeto a manda uma mensagem para objeto b


b usa um parmetro da mensagem para decidir o que fazer
class Lampada {
public final static int ON = 0;
public void setLampada(int valor) {
if(valor == ON) {
// liga lampada
} else if(valor == 1) {
// desliga lampada
} else if(valor == 2) {
// pisca
}
}
}
Lampada lampapa = new Lampada();
lampada.setLampada(Lampada.ON);
lampada.setLampada(2);

Soluo: decompor a operao em mltiplas operaes primitivas


class Lampada {

public void on() { // liga lampada }


public void off() { // desliga lampada }
public void pisca() { // pisca }
}
Lampada lampada = new Lampada();
lampada.on();
lampada.pisca();
Ocorrncia comum:

Objeto a manda mensagem para objeto b


b retorna informao de controle para a
Exemplo: retorno de cdigo de erro
class Teste {
public int printFile(File aImprimir) {
if(aImprimir est corrompido ) {
return CORRUPTFLAG;
}
// etc. etc.
}
}
Teste umTeste = new Teste();
int resultado = umTese.printFile(miniTeste);
if(resultado == CORRUPTFLAG) {
// oh! oh!
} else if(resultado == -243) {
// etc. etc.

Soluo: use excees


class Teste {
public int printFile(File aImprimir) throws PrintExeception {
if(aImprimir est corrompido ) {
throw new PrintExeception();
}
// etc. etc.
}
}
try {
Teste umTeste = new Teste();
umTeste.printFile(miniTeste);
} catch(PrintException printError) {
// mail para a turma: no tem miniteste amanh!
}

Acoplamento de dados globais


Dois ou mais objetos compartilham estruturas de dados globais.
um acoplamento muito ruim pois est escondido.
Uma chamada de mtodo pode mudar um valor global e o cdigo no deixa isso
aparente.
Um tipo de acoplamento muito ruim!

Acoplamento de dados internos


Um objeto altera os dados locais de outro objeto.
Ocorrncia comum:

Friends em C++
Dados pblicos, package visibility ou mesmo protected em java

Use com cuidado!

Consequncias

Uma classe fracamente acoplada no afetada (ou pouco afetada) por


mudanas em outras classes.
Simples de entender isoladamente.
Reuso mais fcil.

Alta Coeso
Problema
Como gerenciar a complexidade?
A coeso mede quo relacionadas ou focadas esto as responsabilidades da classe
Tambm chamada de "coeso funcional" (ver frente)
Uma classe com baixa coeso faz muitas coisas no relacionadas e leva aos
seguintes problemas:

Difcil de entender
Difcil de reusar
Difcil de manter
"Delicada": constantemente sendo afetada por outras mudanas

Uma classe com baixa coeso assumiu responsabilidades que pertencem a outras
classes

Soluo
Atribuir responsabilidades que mantenham alta coeso

Exemplo
Mesmo exemplo usado para Low Coupling
Na primeira alternativa, TPDV assumiu uma responsabilidade de efetuar um
pagamento (mtodo faaPagamento())

At agora, no h problema
Mas suponha que o mesmo ocorra com vrias outras operaes de sistema:

TPDV vai acumular um monte de mtodos no muito focados


Resultado: baixa coeso

A segunda alternativa delega faaPagamento() para a classe Venda

Mantm maior coeso em TPDV

Discusso
Alta coeso outro princpio de ouro que deve ser sempre mantido em mente durante
o projeto
Tipos de coeso entre mdulos:

Coincidente (pior)
Lgico
Temporal
Procedural
De comunicao
Sequencial
Funcional (melhor)

Coeso coincidental
H nenhuma (ou pouca) relao construtiva entre os elementos de um mdulo
No linguajar OO:

Um objeto no representa nenhum conceito OO


Uma coleo de cdigo comumente usado e herdado atravs de herana
(provavelmente mltipla)
class Angu {
public static int acharPadro(String texto, String padro) {
// ...
}
public static int mdia(Vector nmeros) {
// ...
}
public static outputStream abreArquivo(string nomeArquivo) {
// ...
}
}
class Xpto extends Angu { // quer aproveitar cdigo de Angu
...
}

Coeso lgica
Um mdulo faz um conjunto de funes relacionadas, uma das quais escolhida
atravs de um parmetro ao chamar o mdulo
Semelhante a acoplamento de controle
Cura: quebrar em mtodos diferentes
public void faa(int flag) {
switch(flag) {
case ON:
// coisas para tratar de ON
break;
case OFF:
// coisas para tratar de OFF
break;
case FECHAR:
// coisas para tratar de FECHAR
break;
case COR:
// coisas para tratar de COR
break;
}
}

Coeso temporal
Elementos esto agrupados no mesmo mdulo porque so processados no mesmo
intervalo de tempo
Exemplos comuns:

Mtodo de inicializao que prov valores defaults para um monte de coisas


diferentes
Mtodo de finalizao que limpa as coisas antes de terminar
procedure inicializaDados() {
font = "times";
windowSize = "200,400";
xpto.nome = "desligado";
xpto.tamanho = 12;
xpto.localizao = "/usr/local/lib/java";
}

Cura: usar construtores e destrutores


class Xpto {
public Xpto() {
this.nome = "desligado";
this.tamanho = 12;
this.localizao = "/usr/local/lib/java";
}
}
Outro exemplo: arquivo de configurao tpico
[Macintosh]
EquationWindow=146,171,406,661
SpacingWindow=0,0,0,0
[Spacing]
LineSpacing=150%
MatrixRowSpacing=150%
MatrixColSpacing=100%
SuperscriptHeight=45%
SubscriptDepth=25%
LimHeight=25%
LimDepth=100%
LimLineSpacing=100%
NumerHeight=35%
DenomDepth=100%
FractBarOver=1pt
FractBarThick=0.5pt
SubFractBarThick=0.25pt
FenceOver=1pt

SpacingFactor=100%
MinGap=8%
RadicalGap=2pt
EmbellGap=1.5pt
PrimeHeight=45%
[General]
Zoom=200
CustomZoom=150
ShowAll=0
Version=2.01
OptimalPrinter=1
MinRect=0
ForceOpen=0
ToolbarDocked=1
ToolbarShown=1
ToolbarDockPos=1
[Fonts]
Text=Times
Function=Times
Variable=Times,I
LCGreek=Symbol,I
UCGreek=Symbol
Symbol=Symbol
Vector=Times,B
Number=Times
[Sizes]
Full=12pt
Script=7pt
ScriptScript=5pt
Symbol=18pt
SubSymbol=12pt

Coeso procedural
Associa elementos de acordo com seus relacionamentos procedurais ou algortmicos
Um mdulo procedural depende muito da aplicao sendo tratada

Junto com a aplicao, o mdulo parece razovel


Sem este contexto, o mdulo parece estranho e muito difcil de entender

No pode entender o mdulo sem entender o programa e as condies que existem


quando o mdulo chamado
Cura: reprojete o sistema!

Coeso de comunicao
Todas as operaes de um mdulo operam no mesmo conjunto de dados e/ou
produzem o mesmo tipo de dado de sada
Cura: isole cada elemento num mdulo separado
"No deveria" ocorrer em sistemas OO usando polimorfismo (classes diferentes para
fazer tratamentos diferentes nos dados)

Coeso sequencial
A sada de um elemento de um mdulo serve de entrada para o prximo elemento
Cura: decompor em mdulos menores

Coeso funcional (a melhor)


Um mdulo tem coeso funcional se as operaes do mdulo puderem ser descritas
numa nica frase de forma coerente
Num sistema OO:

Cada operao na interface pblica do objeto deve ser funcionalmente coesa


Cada objeto deve representar um nico conceito coeso

Exemplo: um objeto que esconde algum conceito ou estrutura de dados ou recurso e


onde todos os mtodos so relacionados por um conceito ou estrutura de dados ou
recurso

Meyer chama isso de "information-strength module"

Consequncias

Melhor claridade e facilidade de compreenso do projeto


Simplificao da manuteno
Frequentemente vai mo na mo com acoplamento fraco
Com granularidade baixa e funcionalidade bem focada, aumenta o reuso

Você também pode gostar