Princípios de Modularidade III
Aula 06
Agenda
• Composição genérica de um módulo • Processo de desenvolvimento genérico
Objetivo
Ampliar a abrangência dos conceitos de módulos de definição e implementação para outros elementos que são utilizados ao compor programas.
Descrever um processo de desenvolvimento típico para programas C
Referência
Composição de um programa modular simples
Exporta I m p o r t a Módulo 1 Exporta I m p o r t a Módulo 2 Exporta I m p o r t a Módulo 3 Cliente Servidor Exporta Ambiente I m p o r t a Módulo 4 Suporte Exporta I m p o r t a Módulo 5 AmbienteAssume que existem somente interfaces do gênero código Na realidade temos vários outros tipos de interface
Revisão garantia de integrabilidade de módulos
Para assegurar que os módulos se integrem corretamente, o compilador deve usar exatamente a mesma declaração de interface para compilar
• o módulo servidor
• todos os módulos cliente de um determinado servidor
A interface deve então estar contida em um arquivo a ser incluído tanto pelo correspondente servidor com por todos os seus clientes
Aspectos da interface que não puderem ser controlados pelo compilador devem ser especificados através
• de comentários
• de texto redigido em alguma outra linguagem adicionada sob a forma de comentários
• exemplo comentários marcados para a geração automática de documentação
• especificação da semântica (significado e unidades de medida) de variáveis para permitir o controle da corretude de uso em expressões
Tabelas de definição
Semelhantes aos dos módulos de definição, as tabelas de definição asseguram a consistência da interface entre módulos de implementação e tabelas ou
arquivos manipulados
• estabelecem a interface entre o módulo de implementação e uma tabela ou arquivo
• usualmente formados por declarações de constantes correspondentes a chaves de acesso
• redigidos sob a forma de listas de constante simbólicas
• podem conter declarações da organização das tabelas ou arquivos Exemplos de tabelas de definição:
• C
#define BT_ERR_NO_FIRST_NODE 101 #define BT_ERR_KEY_IN_NODE 102 #define BT_ERR_NO_KEY_IN_NODE 103 • C++ ou sub-conjunto C de C++
const int BT_ERR_NO_FIRST_NODE = 101 ; const int BT_ERR_KEY_IN_NODE = 102 ; const int BT_ERR_NO_KEY_IN_NODE = 103 ;
Tabela de implementação: Exemplo de interface com uma tabela de strings
Windows
#include "STRBTERR.INC" STRINGTABLE
BEGIN
BT_ERR_NO_FIRST_NODE "BT %k1 is not the first in node %n2" BT_ERR_KEY_IN_NODE "BT %k1 found in node %n2"
BT_ERR_NO_KEY_IN_NODE "BT %k1 not found in node %n2" END
Um string é recuperado da tabela usando a função LoadString( ... , BT_ERR_NO_FIRST_NODE, ... ) ;
Interface entre módulos generalizada
Tabela de definição (x.inc)
• Define a interface do tipo código
Tabelas de implementação (x.tab)
• são dados que formam um todo coeso e são armazenados em separado. Exemplo de tabela de implementação de strings
static const int NUM_STR_MEM = 155 ; // Resident string type descriptor struct tpStr
{
unsigned long idStr ; int TamStr ;
int inxStrTxt ; // identifica o vetor de texto int inxStrTxtOrg ; // origem no vetor de texto } ;
static tpStr vtStrMem[ NUM_STR_MEM ] = { { 11 , 42 , 0 , 0 } , { 12 , 25 , 0 , 43 } , { 51 , 27 , 0 , 69 } , . . . static char StrTxt_0[ ] =
"Attempt to convert an illegal ASCII number\0" "Overflow in BCD operation\0"
"Error in counter structure.\0" . . .
static char * vtpStrTxt[ 6 ] = { StrTxt_0 , . . .
Tabelas de declaração
Outro exemplo, tabela de definição consistente com a tabela de implementação acima
const int BCD_ErrorASCII = 11 ; const int BCD_ErrorOverflow = 12 ; const int CNT_ErrorVerify = 51 ;
Para assegurar a consistência do acesso a tabelas e arquivos deve-se utilizar • chaves utilizadas tanto pela implementação como pela definição devem ser
iguais
• o módulo que encapsula a tabela de implementação utiliza os dados da tabela de definição para ter acesso à tabela
Através de chaves de acesso definidas através de constantes simbólicas, pode-se ter acesso ao elemento depode-sejado, utilizando um nome simbólico
• nomes simbólicos são mais fáceis de memorizar
• nomes simbólicos permitem verificar se o item da tabela a ser acessado é o correto
• nomes simbólicos permitem o uso de ferramentas de geração a partir de uma linguagem de especificação
Com uma tabela de declaração (.defstr) e duas ferramentas pode-se trabalhar com uma tabela de declaração e gerar as tabelas de definição e de implementação.
Exemplo
BCD_ErrorASCII 11 "Attempt to convert an illegal ASCII number" BCD_ErrorOverflow 12 "Overflow in BCD operation"
Composição de um módulo fonte a ser compilado
Um módulo
• é uma unidade de compilação
• estabelecida pelo módulo de implementação • um arquivo fonte x.c
• O módulo de implementação inclui (#include) diversos outros arquivos • módulos de definição • tabelas de definição • tabelas de implementação • descritores de menus • descritores de diálogos • tabelas de código SQL • . . . M1.C D2.INC T1.TAB D1.INC Módulo fonte Interface com clientes Tabelas de definição importadas Tabelas de definição Tabelas de implementação Código a compilar Módulo de definição disponibilizado Módulo de implementação
Arquivos incluídos no módulo de implementação
Módulos de definição importados
Arquitetura de programas
Arquitetura é o processo de organizar o programa em termos de módulos
• projeto conceitual • design
Projeto é o processo de organizar um módulo em termos de suas funções
• projeto detalhado • design
A arquitetura de um programa define um esqueleto de módulos • especifica para cada um dos módulos
• o seu objetivo
• a sua interface que disponibiliza: módulo de definição próprio • a qualidade requerida
• as interfaces que utiliza
A arquitetura deve procurar resolver o problema proposto • com um mínimo de compromissos
• produzindo módulos que possam ser reutilizados em diversos programas • implementam um único assunto
• produzindo módulos e programas manuteníveis • elevado encapsulamento
• baixo acoplamento • elevada coesão
Processo de desenvolvimento simples
Compilador Compilador Compilador Ligador M3.OBJ M2.OBJ M1.OBJ L2.LIB L1.LIB PG.EXE Editor de programas M3.HPP M3.CPP M2.HPP M2.CPP M1.HPP M1.CPPPrograma
Processo de desenvolvimento complexo
Editor Editor Compilador Compilador de recursos Ligador M3.HPP M3.CPP M2.HPP M2.CPP M1.HPP M1.CPP M3.OBJ M2.OBJ M1.OBJ D2.INC D1.INC D2.RES D1.RES R2.RES R1.RES L2.LIB L1.LIB PG.EXE Nomes simbólicosOrganização física
É fortemente recomendável criar uma estrutura de diretórios (pastas) para cada projeto
• pastas com menos arquivos são mais fáceis de manipular + Projeto X
|
+ Composicao contem arquivos .make, .comp, ... + ModulosFonte contém arquivos .c, .h, ...
+ ModulosObjeto contém arquivos .obj, .build, ... + Produto contém arquivos .exe, .log, ...
+ Tabelas contém arquivos .tabstr, .incstr, ... + Teste contem arquivos .script, .count, ... + ... (por exemplo os de apoio ao ambiente)