@Roberto S. Bigonha Modularidade 1
Programação Modular em C++
MODULARIDADE
Roberto S. Bigonha
Laboratório de Linguagens de Programação Departamento de Ciência da Computação
Universidade Federal de Minas Gerais 13 de outubro de 2008
Todos os direitos reservados Proibida a cópia sem autorização dos autores
@Roberto S. Bigonha Modularidade 2
ESTRUTURAÇÃO DE DE
SOFTWARE EM CAMADAS
Modelo de Camadas
! Camadas de software permitem distribuir melhor as funções de uma aplicação
! Camadas disciplinam direção do fluxo de mensagens entre certos tipos de classes
! A direção do fluxo de mensagens entre camadas normalmente é pré-definida e deve ser observada pelo programador
! Mensagem significa chamar o método de um objeto, i.e., mandar uma msg para o objeto receptor
! Mensagem equivale a uma solicitação de serviço a um objeto
! A resposta do objeto receptor da mensagem não é considerada uma mensagem
! A mensagem é só na direção do objeto receptor
Modelo de Quatro Camadas
•Camada de Sistema •Camada de Interface do Usuário • Camada de Negócio •Camada de Persistência Camada de Sistema Camada de Interface Camada de Negócio Camada de Persistência Banco de Dados A B = Asolicita serviço de B@Roberto S. Bigonha Modularidade 5
Organização de Camadas em C++
!C++ não oferece recursos lingüísticos para
controlar a direção do fluxo de mensagens
!Controle da direção do fluxo de mensagens
entre camadas é de responsabilidade do programador
!Uma camada de software em C++ pode ser
organizada como um conjunto de módulos
@Roberto S. Bigonha Modularidade 6
Vantagens do Modelo de Camadas
!Camadas contribuem para aumentar
– extensibilidade – manutenabilidade – portabilidade
!Se as mensagens fluem sempre da Camada
de Interface para a Camada de Negócio, então pode-se trocar a interface sem afetar as classes de negócio
!Dentro de uma camada, mensagens podem
fluir livremente
Extensibilidade do Sistema
! O ponto fundamental do conceito de camadas é
a descoberta de que as mensagens são unilaterais
! Troca de interface não tem efeito na camada
de negócios e nem na camada de persistência
! Troca do banco de dados pode afetar a camada
de persistência, mas não a camada de negócios e muito menos a interface
A Camada de Sistema
!Conjunto de bibliotecas que:– fornece acesso a recursos de hardware, do Sistema Operacional, dos dispositivos de comunicação
– permite manipulação de tipos de dados universais
– permite acesso a bibliotecas de propósito geral
!Provê funções específicas do ambiente de
@Roberto S. Bigonha Modularidade 9
A Camada de Sistema ...
!Empacota funções do Sistema Operacional, de
outras ferramentas ou aplicação de terceiros
!Em geral, a Camada de Sistema recebe
mensagens de todas as outras camadas
!Classes de sistema podem ser desenvolvidas
sem quaisquer informações dos usuários
!Classes de sistema são aquelas que
geralmente precisam ser modificadas se o S.O. for atualizado
@Roberto S. Bigonha Modularidade 10
A Camada de Sistema
!Ocasionalmente, o fluxo de mensagens pode
ter origem na Camada de Sistema !Métodos de rechamada (callback):
Objeto A envia mensagem a B, solicitando que B envie uma mensagem de volta quando certo evento ocorrer
!Portanto, fluxo de mensagens com Camada de Sistema pode ser bi-direcional
A Camada de Interface
!Conjunto de classes que permitem implementar
a interação dos usuários com a aplicação
!Responsável pela interface gráfica de usuário
(GUI) para a aplicação, geram-se relatórios, etc
! As mensagens devem fluir Camada de Interface para a Camada de Negócio, e nunca no sentido contrário:
" Mudanças na interface não afetam a Camada
de Negócio
! Não deve haver fluxo de mensagens entre a Camada de Interface e a de Persistência
A Camada de Negócios
! Encapsula um conjunto de classes do domínio da aplicação ou do negócio
! Classes de Negócio são as classes identificadas durante a análise
! Encapsula a funções da aplicação, sem se preocupar com interface de usuário, administração de dados e detalhes de sistema
! O fluxo de mensagens é no sentido da Camada de
Interfacepara Camada de Negócio e desta para a
Camada de Persistência
! Excepcionalmente, pode haver o fluxo bi-direcional de mensagens entre a Camada de Negócio e a de Sistema
! Classes de Negócio, em geral, não são afetadas quando transportadas para outro ambiente
@Roberto S. Bigonha Modularidade 13
A Camada de Persistência
!Encapsula um conjunto de classes para prover
acesso aos dados de armazenamento permanente.
! Não é o Banco de Dados.
!É apenas um front-end que empacota o acesso
ao Banco de Dados.
!Torna a aplicação independente do SGBD e suas
versões.
!Classes de Persistência em geral devem ser
modificadas quando o sistema de arquivos ou banco de dados for atualizado.
@Roberto S. Bigonha Modularidade 14
CONCEITO DE MÓDULO
Módulo
!MÓDULO é um componente de software
compilável separadamente, por exemplo:
–
procedimento externo
–unit do Turbo Pascal
–arquivo fonte em Java
–pacote da ADA
–
module de Oberon-2
–
arquivo fonte em C e C++
Modularidade
!MODULARIDADE é a chave para o
desenvolvi-mento de software com arquitetura flexível
!Modularidade permite atingir: extensibilidade
e reusabilidade
!POO possibilita e prioriza a criação de módulos
mais flexíveis
!Módulos implementam abstrações
!O módulo é a única ferramenta disponível para quebrar a complexidade e baixar o custo do software (Parnas)
@Roberto S. Bigonha Modularidade 17
Conceito de Abstração
!Abstração é um modo de pensar no qual
concentra-se na idéia e não nas manifestações específicas desta idéia
!Abstrair-se significa concentrar-se no que o
programa faz e não em como ele faz
!Abstração é o elemento básico de construção de
módulos
!Abstração depende dos objetivos de quem se
abstrai
!Por exemplo, a abstração da entidade pessoa
depende de seu uso no sistema
@Roberto S. Bigonha Modularidade 18
Conceito de Abstração ...
!Abstração depende dos objetivos de quem se
abstrai. Por exemplo, a abstração da entidade pessoa depende de seu uso no sistema
!Uma pessoa sob a perspectiva de um médico:
!Uma pessoa sob a perspectiva do emprego: Pessoa
estado civil
nome cpf endereço dependentes
Pessoa Coração
Cérebro Pressão Rim Pulmão
Tipos de Abstração
1. FUNÇÃO:# Conjunto encapsulado de declarações e comandos que calcula um valor
e possivelmente causa um efeito colateral no ambiente
2. PROCEDIMENTO
# Conjunto encapsulado de declarações e comandos que deve causar um
efeito colateral no ambiente
3. ABSTRAÇÃO DE DADOS
# Estrutura de dados definida pelas suas operações # Representação encapsulada
4. TIPO ABSTRATO DE DADOS # Tipo definido pelas suas operações # Representação encapsulada
5. TIPO ABSTRATO DE DADOS PARAMETRIZADO # Tipo definido pelas suas operações
# Representação parametrizada e encapsulada
Princípio da Unidade Linguística
! A todo tipo abstração realizável na linguagem devecorresponder um tipo de módulo.
! Deve existir um tipo de módulo para implementar as principais
abstrações correspondentes às principais construções da linguagem:
! A linguagem deve prover o suporte lingüístico para a realização das
abstrações
! Sem o suporte lingüístico é muito difícil realizar manutenção em
software de grande porte
! A linguagem efetivamente modular deve prover recursos para construir
módulos para cada uma das abstrações
Expressões Funções Comandos Procedimentos Declarações de variáveis Abstração de Dados Definições de tipo Tipos Abstratos de Dados Def. de tipos param Tipos Parametrizados
@Roberto S. Bigonha Modularidade 21
MÓDULOS EM LINGUAGENS
ORIENTADAS POR OBJETOS
@Roberto S. Bigonha Modularidade 22
Módulos em Linguagens OO
!Módulo é uma porção de programa compilada separadamente
!Geralmente, em LOO, a classe a menor porção
compilável separadamente
!Módulo normalmente é incorporado ao
programa na forma de código compilado
!Módulos OO são o empacotamento de:
– Tipos Relacionados – Rotinas Relacionadas – Dados Relacionados
Tipos de Módulos
!Módulo Tipos Abstratos de Dados (TAD) !Módulo Rotinas Relacionadas (RR)
!Módulo Declarações de Dados (DD) !Módulo Agrupamento Geral (AG)
Módulo Tipo Abstrato de Dados
# Arquivo contendo uma ou mais classes.
# O módulo implementa um ou mais tipos abstratos de
dados.
class Pilha {
int* elementos; int size; int top; public:
Pilha(int size):top(-1) { this->size = size;
elementos = new int[size]; }
void push(int x) throw(Overflow){ ...} int pop( ) throw(Underflow) { ... } bool empty( ) { ... }
@Roberto S. Bigonha Modularidade 25
Módulo Rotinas Relacionadas
!não possui declarações de dados
! possui uma coleção de rotinas relacionadas ! as rotinas operam apenas em seus parâmetros
! Exemplo: pacote gráfico, pacote rotinas matemáticas
class Math { public:
static float sin(float x); static float log(float x); static float abs(float x); ...
};
@Roberto S. Bigonha Modularidade 26
Módulo Declaração de Dados
#arquivo contendo apenas declarações de dados. class MeusDados { .... public: String usuários[100]; Communicator c; Connection conexao; ... };
Módulo Agrupamento Geral
#Arquivo contendo definições de tipos, declarações de
dados e de rotinas, todos sem qualquer relação entre si
class Ag { .... public: atributos diversos; métodos diversos };
Exemplos de Módulos de Um Componente
class T { int a; int b;
struct X {int a; int b;...} public: void op1(...) {... X ... a ... b ...} friend class U; }; class U { T::X x; int c; public: void op2( ) { ... a .... b ... c ... x ... } };
@Roberto S. Bigonha Modularidade 29
ACOPLAMENTO DE MÓDULOS
@Roberto S. Bigonha Modularidade 30
Acoplamento de Módulos
!Definido em 1975 por Glenford Meyers
!Acoplamento mede o grau de intensidade da
interconexão entre dois módulos
!Acoplamento é uma medida da independência entre
módulos
!O tipo de acoplamento fornece informação para
melhorar a modularidade de um sistema
!Quanto mais fraco o relacionamento entre os
módulos, mais modular é o projeto
!Há dois conceitos:
– interconexão de módulos (conectividade) – intensidade da interconexão (acoplamento)
Módulos de Glenford Meyers
! Em 1975, tipos abstratos de dados eram
conceitos incipientes
! Módulos eram essencialmente abstrações de
procedimentos e funções
! Módulos eram apenas procedimentos externos
! Glenford Meyer, na época, classificou os graus ou
intensidade de acoplamento de módulos em sete níveis
Acoplamento de Módulos G. Meyers
1.Desacoplado: nenhuma comunicação entre módulos 2. Por Informação: comunicação entre módulos unicamente via
chamada de métodos com parâmetros passados por valor 3. Por Referência (stamp):comunicação entre módulos
unicamente via chamada de rotinas, mas há parâmetros por referência
4. Por Controle: um módulo conhece a implementação do método de outro e então passa-lhe parâmetros para controlar seu fluxo de execução
5. Por Dado Externo: módulos têm acesso a objetos comuns, mas alteração destes objetos não afeta todos
6. Por Dado Comum: módulos têm acesso a conjunto comum de objetos. Toda mudança no conjunto afeta todos módulos
7. Por Conteúdo: um módulo tem acesso direto e sub-reptício a campos não-exportados de outro módulo
@Roberto S. Bigonha Modularidade 33
Módulos em POO
! O menor módulo em POO consiste em apenas uma
classe pública
! Módulo visto como sinônimo de classe pública ! Métodos definidos dentro de uma classe não são
vistos como módulos, sejam eles públicos ou não
! O relacionamento entre métodos de classes
distintas forma o relacionamento das respectivas classes
! Acoplamento de classes trata, portanto, do
inter-relacionamento de seus métodos
! A interação entre métodos de uma mesma classe
está relacionada com a coesão interna da classe
@Roberto S. Bigonha Modularidade 34
Acoplamento de Módulos em POO
1. Desacoplado: nenhuma comunicação entre módulos. 2. Por Informação: comunicação entre módulos via
chamada de métodos com parâmetros passados por valor
3. Por Referência: comunicação via chamada de métodos
com parâmetros por referência
4. Por Controle: módulo conhece a implementação do
método de outro módulo e então passa-lhe parâmetros para controlar seu fluxo de execução
5. Por Dado Externo: módulos dependem de software
escritos por terceiros
6. Por Inclusão: módulo inclui código-fonte de outro
componente
7. Por Dado Comum: módulos distintos têm acesso
previsto a objeto comum declarado globalmente
8. Por Conteúdo: módulo tem acesso direto e sub-reptício a
campos de objetos de outro módulo
Acoplamento por Conteúdo
! Um módulo tem acesso direto e sub-reptício a
campos de dados de outro módulo
! Ocorre sempre que se modifica o valor de um
campo de um módulo de uma forma que o projetista do sistema não previu
! Exemplo: define-se uma pilha via suas
operações, mas acidentalmente deixa-se um caminho de acesso direto à sua representação, o qual pode ser usado sub-repticiamente
! Pode ser evitado em C++ sempre declarando
todos os campos de toda classe como privados
Acoplamento por Dado Comum.
1.
! Módulos distintos têm acesso previsto pelo
projetista à estrutura de objeto comum declarado globalmente
! Modificações na estrutura do objeto comum
podem ter impacto em todos os módulos envolvidos
! As modificações em um módulo podem afetar o
funcionamento de todos os outros
! Pode ser evitado fazendo acessos a dados
comuns exclusivamente via chamadas de métodos públicos
@Roberto S. Bigonha Modularidade 37
Acoplamento por Dado Comum...
# Exemplo: módulos DD e seus usuários
!"#$$%&%'%%(((( )*+,%-.%/%'%(((%011)234 5%67%(((%8 87 !"#$$%9%'%%((( )*+,%:.%/%'%(((%;5011)2<47(((%8 87 !"#$$%0%'
=>?"+!1%$@#@+!%+A@B%)5%ACD%+A@ 2EF47 87
! Cada posição de v tem um significado próprio ! O acoplamento existe entre todos os módulos
envolvidos
@Roberto S. Bigonha Modularidade 38
Acoplamento por Inclusão
! Módulo inclui código fonte de outro componente ! Todos os que incluem estão acoplados entre si e
também com o texto incluído
! Reúso do componente implica no réuso das
inclusões G+A!">,C%9(H7 !"#$$%0%' &B%#%5%ACD%.(((/7 I #JK-.((/7%((( 87 G+A!">,C%9(H7 !"#$$%L%' &B%#%5%ACD%.(((/7 ((((((%#JK-.((/7%(((% 87
Acoplamento por Elemento Externo
! Módulo tem acesso a componentes individuais de
objetos comuns
! Modificação no objeto comum não necessariamente
afeta todos
! Implicação: reúso de um componente implica na
importação de todos com os quais há o acoplamento
! Pode ser minimizado via padrão fachada ou
reduzindo pontos onde a dependência existe
Acoplamento por Elemento Externo ...
! Exemplo: módulos DD e seus usuários
!"#$$%&%' M%@7%(((%@(6 5%(((7%(((%@(D ((( 87 !"#$$%9%' M%N7%(((%O%5%N(P./7%(((%N(D%((( 87 !"#$$%M%' =>?"+!1 +A@ D7 -"*#@%67 +A@ P.%/%'(((8 87
@Roberto S. Bigonha Modularidade 41
Acoplamento por Controle
! Um módulo conhece a implementação dos
métodos de outro e então passa-lhes parâmetros para controlar seu fluxo de execução:
public: void rotina(String comando) {
if (comando.equals(“desenhe circulo”) desenheCirculo( );
else desenheRetangulo( ); }
! Implicação: sempre que surgir um novo
comando, rotina deverá ser modificada
! Pode ser evitado chamando diretamente as
funções desejadas: x.desenhe();
@Roberto S. Bigonha Modularidade 42
Acoplamento por Referência
! Comunicação entre módulos unicamente via chamada de métodos, mas há parâmetros por referência (stamp) ! Os componentes acoplados desta forma modificam ou
acessam dados um do outro class A {
...
public: void muda(int& x) { x = 100; } }; class B{ A a; int c; public: void f ( ) { a.muda(c); } };
Acoplamento por Informação
! Comunicação entre módulos unicamente via chamada de métodos com parâmetros passados por valor
! Dependência apenas no significado do dado passado por valor !"#$$ &%'%%% (((((%%% =>?"+!1%)*+, Q>,#.+A@ R/%' R%5%SFF7 8% 87 =>?"+! !"#$$ 9' &%#%%5%ACD%&%.%/7%%% +A@%!7%((( =>?"+!1%)*+, -%.%/%'% #(Q>,#.!/7 8%% 87
Grau de Acoplamento Ideal
! desacoplado@Roberto S. Bigonha Modularidade 45
COESÃO INTERNA DE
MÓDULOS
@Roberto S. Bigonha Modularidade 46
Coesão Interna de Módulos
!Coesão interna de um módulo trata do
relacionamento entre seus elementos
!Seja elemento qualquer parte de um módulo, i.e.,
declarações de variáveis, comandos, etc
!A idéia central é que elementos fortemente
relacionados fiquem confinados em um mesmo módulo, e aqueles não-relacionados sejam encapsulados em módulos separados
!Glenford Meyer, em 1975, classificou os graus de
coesão interna de módulos em sete níveis.
!Módulos, na época, eram procedimentos ou
funções externas, TAD estava apenas surgindo
Graus de Coesão Segundo G. Myers
1. Funcional:cada módulo realiza uma única função
2. Informacional: módulo implementa TAD
3. Comunicacional: ações do módulo são dependentes de dados comuns
4. Procedimental: similar ao clássico, mas as ações estão relacionadas com o problema e há uma ordem de execução
5. Clássica: as ações contidas no módulo somente têm relação temporal e são sobre diferentes objetos
Ex: módulo que abre/fecha todos os arquivos 6. Lógica: módulo com mais de uma função a ser
escolhida pelo usuário via parâmetro
7. Coincidental: módulo contém ações não relacionadas
Coesão Coincidental de Myers
!Módulo que contém elementos não-relacionados !Em geral, é resultado de:– modularização feita posteriormente
– criação de módulo para evitar duplicação de código (((( #%5%?%T%!7 ,%5%R(:C@+A@.%/7 !*>@ UU%H7 +-%%.N%5%$%/%'%(((8%C"$C%'%((8 ((((
novo módulo
@Roberto S. Bigonha Modularidade 49
Coesão Lógica de Myers
!Módulo com mais de uma função a ser escolhida
pelo usuário via parâmetro
!Os elementos têm relação lógica, mas têm
funções distintas e independentes
!Melhor seria um procedimento para cada função !Exemplo: um único procedimento faz inserção,
remoção e pesquisa de um valor em uma tabela
@Roberto S. Bigonha Modularidade 50
Coesão Clássica de Myers
!Ações contidas no módulo somente têm entre si
relação temporal
!Estas ações estão relacionadas com a
implementação e não com o problema
!Essas ações operam sobre diferentes objetos ! Exemplos:
– módulo que abre/fecha todos os arquivos – módulo que faz todas as inicializações !Melhor quando cada módulo faz sua própria
inicialização e arquivos abertos à medida que forem necessários
Coesão Procedimental de Myers
!Similar à clássica, mas as ações do móduloestão relacionadas com o problema e não com o momento em são executadas
!Módulo resultante da encapsulação de ações
seqüenciais do “fluxograma”
!Ações não processam dados comuns !Exemplos:
– atualize a ficha e leia a próxima transação – x.calcula A; y.imprime B
Coesão Comunicacional de Myers
! Similar ao procedimental, mas as ações domódulo comunicam-se entre si
! Ações são dependentes de dados comuns:
– Ex.: grave a ficha no BD e a registre no arquivo de log
! Uma ação gera dados que são usados pela ação
seguinte:
– Ex.: calcula trajetória e a envia para o terminal
@Roberto S. Bigonha Modularidade 53
Coesão Informacional de Myers
!Módulo implementa um conjunto de operações,
ativáveis independentemente
!Suas operações atuam sobre dados comuns e
encapsulados
!As operações são relacionadas e operam de
forma relevante sobre os dados comuns
!Exemplo: classe que implementa um TAD
@Roberto S. Bigonha Modularidade 54
Coesão Funcional de Myers
!Módulo realiza uma única função
!Todos seus elementos contribuem para a
execução de uma única função
Coesão Interna de Métodos
Coesão Interna de Métodos
1. Funcional:método realiza uma única função
2. Comunicacional:ações do método são dependentes de dados comuns
3. Procedimental:similar ao clássico, mas as ações estão relacionadas com o problema e há uma ordem de
execução
4. Temporal (clássica): método que executa diferentes ações, relacionadas no tempo, sobre diferentes objetos.
Ex: método para abrir/fechar todos os arquivos 5. Lógica: método com mais de uma função a ser escolhida
pelo usuário via parâmetro
6. Coincidental: método executando ações não relacionadas
@Roberto S. Bigonha Modularidade 57
Coesão Interna de Classes
@Roberto S. Bigonha Modularidade 58
Coesão Interna de Classes
!O comportamento de uma classe é formado pelo
conjunto dos comportamentos de seus métodos públicos
!Portanto, as qualidades ou defeitos no
comportamento de métodos fazem parte do perfil da respectiva classe
!Coesão interna de uma classe depende do grau
de coesão interna de seus métodos
!Coesão interna da classe depende também da
coesão entre os seus métodos
Graus de Coesão Interna de Classe
1. Contratual: implementa um único contrato, seus métodos têm coesão funcional
2. Comunicacional: contém métodos de coesão comunicacional
3. Procedimental: contém métodos de coesão procedimental ou métodos em que a ordem de execução é relevante
4. Temporal: contém elementos de coesão clássica ou temporal
5. Lógica: contém elementos de coesão lógica. 6. Coincidental: implementa mais de um
contrato, contém métodos não-relacionados, métodos de coesão coincidental ou dados não relacionados
Classe de Coesão Coincidental
! Classe que implementa mais de um contrato, contém métodos não-relacionados, métodos de
coesão coincidental ou dados não relacionados
! Classe com mais de um contrato
! Classe contendo métodos não-relacionados ! Classe com métodos de coesão coincidental ! Classe com dados não-relacionados
@Roberto S. Bigonha Modularidade 61
Classe de Coesão Lógica
! Classe com métodos de coesão lógica ! Métodos com coesão lógica deviam ser
divididos em outros, um para cada uma de suas funções
! Classe com mais de um contrato relacionados
logicamente
! Exemplo: class Modem {
public: void discar( ){...} void desligar( ) { ...} void enviar( ) { ...} void receber() { ...} };
@Roberto S. Bigonha Modularidade 62
Classe de Coesão Temporal
! Classe com métodos de coesão temporal ! Classe com um conjunto de métodos que
precisam ser executadas em conjunto e em determinada seqüência
! Exemplo: classe com métodos que se
destinam a iniciar o ambiente de execução: class Ambiente{
public:
void abreArquivodeDados ( ) { ... } void abreArquivodeLog ( ) { ... } };
Classe de Coesão Procedimental
! Classe com um ou mais métodos de coesãoprocedimental
! Classe contendo métodos em que a ordem de
execução é relevante
! Métodos só podem ser executados em
determinada ordem
! Pode ocorrer quando iniciação do objeto é via
método específico e não via construtor
Classe de Coesão Comunicacional
! Classe com um ou mais métodos de coesão
comunicacional
! Métodos da classe dependem de dados
comuns
! Neste caso, trata-se de característica
essencial da Orientação por Objetos
! Normalmente, métodos operam de forma
@Roberto S. Bigonha Modularidade 65
Classe de Coesão Contratual
! Classe que implementa um único contrato ! Seus métodos têm coesão funcional
! Todos seus campos são privados ! Exemplo: classes TAD ou RR
@Roberto S. Bigonha Modularidade 66
Independência de Módulos
# Acoplamento de Módulos: 1. Desaclopado (menor grau) 2. Por Informação
3. Por Referência 4. Por Controle 5. Por Dado Externo 6. Por Inclusão 7. Por Dado Comum
8. Por Conteúdo (maior grau)
# Grau de Coesão Interna de Módulos:
1. Contratual (maior grau) 2. Comunicacional
3. Procedimental 4. Temporal 5. Lógica
6. Coincidental (menor grau)
Para se construir módulos altamente independentes deve-se observar o máximo de coesão internaem cada um e o mínimo de acoplamentoentre eles. (Glenford Meyer)
(melhor)
( pior )