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