Академический Документы
Профессиональный Документы
Культура Документы
Qualidade do software
O principal objetivo da Engenharia de Software contribuir para a produo de programas de
qualidade. Esta qualidade, porm, no uma idia simples; mas sim como um conjunto de noes e fatores.
desejvel que os programas produzidos sejam rpidos, confiveis, modulares, estruturados,
modularizados, etc. Esses qualificadores descrevem dois tipos de qualidade:
De um lado, considera-se aspectos como eficincia, facilidade de uso, extensibilidade, etc.
Estes elementos podem ser detectados pelos usurios do sistema. A esses fatores atribui-se a
qualidade externa do sofware.
Por outro lado, existe um conjunto de fatores do programa que s profissionais de computao
podem detectar. Por exemplo, legibilidade, modularidade, etc. A esses fatores atribui-se a
qualidade interna do sofware.
Na realidade, qualidade externa do programa em questo que importa quando de sua utilizao. No
entanto, os elementos de qualidade interna so a chave para a conquista da qualidade externa. Alguns
fatores de qualidade externa so apresentados na prxima seo. A seo posterior trata da qualidade
interna, analisando como a qualidade externa pode ser atingida a partir desta.
Robustez
a capacidade do programa de funcionar mesmo sob condies anormais.
A robustez do programa diz respeito ao que acontece quando do aparecimento de situaes anmalas.
Isto diferente de corretude, que define como o programa se comporta dentro de sua especificao. Na
robustez, o programa deve saber encarar situaes que no foram previstas sem efeitos colaterais
catastrficos. Neste sentido, o termo confiabilidade muito utilizado para robustez; porm denota um
conceito mais amplo que melhor interpretado como que englobando os conceitos de corretude e
robustez.
Extensibilidade
definida como a facilidade com que o programa pode ser adaptado para mudanas em sua
especificao.
Neste aspecto, dois princpios so essenciais:
Simplicidade de design: uma arquitetura simples sempre mais simples de ser adaptada ou
modificada
Descentralizao: quanto mais autnomos so os mdulos de uma arquitetura, maior ser a
probabilidade de que uma alterao implicar na manuteno de um ou poucos mdulos.
Capacidade de reuso
a capacidade do programa de ser reutilizado, totalmente ou em partes, para novas
aplicaes.
A necessidade de reutilizao vem da observao de que muitos elementos dos sistemas seguem
padres especficos. Neste sentido, possvel explorar este aspecto e evitar que a cada sistema produzido
os programadores fiquem reinventando solues de problemas j resolvidos anteriormente.
Compatibilidade
a facilidade com que o programa pode ser combinado com outros.
Esta uma qualidade importante pois os programas no so desenvolvidos stand-alone. Normalmente,
existe uma interao entre diversos programas onde o resultado de um determinado sistema utilizado
como entrada para outro.
Outros aspectos
Os aspectos resumidos acima so aqueles que podem ser beneficiados com a boa utilizao das
tcnicas de orientao por objetos. No entanto, existem outros aspectos que no podem ser esquecidos:
Eficincia: o bom aproveitamento dos recursos computacionais como processadores,
memria, dispositivos de comunicao, etc. Apesar de no explicitamente citado anteriormente,
este um requisito essencial para qualquer produto. A linguagem C++ em particular, por ser
to eficiente quanto C, permite o desenvolvimento de sistemas eficientes.
Portabilidade: a facilidade com que um programa pode ser transferido de uma plataforma
(hardware, sistema operacional, etc.). Este fator depende muito da base sobre a qual o sistema
desenvolvido. A nvel de linguagem, C++ satisfaz este fator por ser uma linguagem
padronizada com implementaes nas mais diversas plataformas.
Facildade de uso: a facilidade de aprendizagem de como o programa funciona, sua operao,
etc.
Decomposio
O critrio de decomposio modular alcanado quando o modelo de design ajuda a decomposio
do problema em diversos outros subproblemas cujas solues podem ser atingidas separadamente.
O mtodo deve ajudar a reduzir a aparente complexidade de problema inicial pela sua decomposio
em um conjunto de problemas menores conectados por uma estrutura simples. De modo geral, o processo
repetitivo: os subproblemas so tambm divididos em problemas menores e assim sucessivamente.
Uma exemplificao deste tipo de design o chamado mtodo top-down. Este mtodo dirige os
desenvolvedores a comear com uma viso mais abstrata do funcionamento do sistema. Esta viso
abstrata vai sendo refinada como um conjunto de passos sucessivos menores e assim por diante at que
seus elementos estejam em um nvel que permita sua implementao. Este processo pode ser modelado
como uma rvore.
Composio
O mtodo que satisfaz o critrio de composio favorece a produo de elementos de programas que
podem ser livremente combinados com os outros de forma a produzir novos sistemas, possivelmente em
um ambiente bem diferente daquele em que cada um destes elementos foi criado.
Enquanto que a decomposio se concentra na diviso do software em elementos menores a partir da
especificao, a composio se estabelece no sentido oposto: agregando elementos de programas que
podem ser aplicados para construo de novos sistemas.
A composio diretamente relacionada com a questo da reutilizao: o objetivo achar maneiras de
desenvolver pedaos de programas que executam tarefas bem definidas e utilizveis em outros contextos.
Este contexto reflete um sonho antigo: transformar o processo de design de programas como elementos
independentes onde programas so construdos pela combinao de elementos existentes.
Um exemplo deste tipo de abordagem a construo de bibliotecas como conjuntos de elementos que
podem ser utilizados em diversos programas (pacotes grficos, bibliotecas numricas, etc.).
Entendimento
Um mtodo que satisfaz o critrio de entendimento ajuda a produo de mdulos que podem ser
separadamente compreeendidos pelos desenvolvedores; no pior caso, o leitor deve ter ateno sobre
poucos mdulos vizinhos. Este critrio especialmente relevante quando se tem em vista o aspecto da
manuteno.
Um contra-exemplo deste tipo de mtodo quando h dependncia sequencial onde um conjunto de
mdulos elaborado de modo que a execuo dos mesmos seja feita em uma ordem determinada. Desta
forma, os mdulos no so entendidos de forma individual mas em conjunto com seus vizinhos.
Continuidade
Um mtodo de design satisfaz a continuidade se uma pequena mudana na especificao do problema
resulta em alteraes em um nico ou poucos mdulos. Tal alterao no tem reflexos na arquitetura geral
do sistema; isto , no relacionamento inter-modular.
Este critrio reflete o problema de extensibilidade do sistema. A continuidade significa que eventuais
mudanas devem afetar os mdulos individualmente da estrutura do sistema e no a estrutura em si.
Um exemplo simples deste tipo de critrio a utilizao de constantes representadas por nomes
simblicos definidos em um nico local. Se o valor deve ser alterado, apenas a definio deve ser
alterada.
Proteo
Um mtodo de design satisfaz a proteo se este prov a arquitetura de isolamento quando da
ocorrncia de condies anmalas em tempo de execuo. Ao aparecimento de situaes anormais, seus
efeitos ficam restritos quele mdulo ou pelo menos se propagar a poucos mdulos vizinhos.
Os erros considerados neste critrio so somente aqueles ocorridos em tempo de execuo como falta
de espao em disco, falhas de hardware, etc. No se considera, neste caso, a correo de erros, mas um
aspecto importante para a modularidade: sua propagao.
Princpios de modularidade
Estabelecidos os critrios de modularidade, alguns princpios surgem e devem ser observados
cuidadosamente para se obter modularidade. O primeiro princpio se relaciona com a notao e os outros
se baseiam no modo de comunicao entre os mdulos.
Seguem abaixo estes princpios:
Lingustica modular
Este princpio expressa que o formalismo utilizado para expressar o design, programas, etc. deve
suportar uma viso modular; isto :
Mdulos devem correspoder s unidades sintticas da linguagem utilizada.
Onde a linguagem utilizada pode ser qualquer linguagem de programao, de design de sistemas, de
especificao, etc.
Este princpio segue de diversos critrios mencionados anteriormente:
Poucas interfaces
Este princpio restringe o nmero de canais de comunicao entre os mdulos na arquitetura do
sistema. Isto quer dizer que:
Cada mdulo deve se comunicar o mnimo possvel com outros.
A comunicao pode ocorrer das mais diversas formas. Mdulos podem chamar funes de outros,
compartilhar estruturas de dados, etc. Este princpios limita o nmero destes tipos de conexo.
Pequenas interfaces
Este princpio relaciona o tamanho das interfaces e no suas quantidades. Isto quer dizer que:
Se dois mdulos possuem canal de comunicao, estes devem trocar o mnimo de informao
possvel; isto , os canais da comunicao inter-modular devem ser limitados.
Interfaces explcitas
Este um princpio que vai mais adiante do que poucas interfaces e pequenas interfaces. Alm de
impor limitaes no nmero de mdulos que se comunicam e na quantidade de informaes trocadas, h a
imposio de que se explicite claramente esta comunicao. Isto :
Quando da comunicao de dois mdulos A e B, isto deve ser explcito no texto de A, B ou
ambos.
Este princpio segue de diversos critrios mencionados anteriormente:
Decomposio e composio: Se um elemento formado pela composio ou decomposio
de outros, as conexes devem ser bem claras entre eles.
Entendimento: Como entender o funcionamento de um mdulo A se seu comportamento
influenciado por outro mdulo B de maneira no clara?
Calculadora RPN em C
Os primeiros exemplos sero feitos a partir de um programa escrito em C. Vrias modificaes sero
feitas at que este se torne um programa C++. O programa uma calculadora RPN (notao polonesa
reversa), apresentada nesta seo.
Este tipo de calculadora utiliza uma pilha para armazenar os seus dados. Esta pilha est implementada
em um mdulo parte. O header file et listado abaixo:
#ifndef stack_h
#define stack_h
#define MAX 50
struct Stack {
int top;
int elems[MAX];
};
void push(struct Stack* s, int i);
int pop(struct Stack* s);
int empty(struct Stack* s);
struct Stack* createStack(void);
#endif
A implementao destas funes est no arquivo stack-c.c:
#include <stdlib.h>
#include "stack-c.h"
void push(struct Stack*s, int i) { s->elems[s->top++] = i; }
int pop(struct Stack*s)
{ return s->elems[--(s->top)]; }
int empty(struct Stack*s)
{ return s->top == 0; }
struct Stack* createStack(void)
{
struct Stack* s = (struct Stack*)malloc(sizeof(struct Stack));
s->top = 0;
return s;
}
A calculadora propriamente dita utiliza estes arquivos:
#include <stdlib.h>
#include <stdio.h>
#include "stack-c.h"
/* dada uma pilha, esta funo pe nos
parmetros n1 e n2 os valores do topo
da pilha. Caso a pilha tenha menos de dois
valores na pilha, um erro retornado */
int getop(struct Stack* s, int* n1, int* n2)
{
if (empty(s))
{
printf("empty stack!\n");
return 0;
}
*n2 = pop(s);
if (empty(s))
{
push(s, *n2);
printf("two operands needed!\n");
return 0;
}
*n1 = pop(s);
return 1;
}
Classes em C++
Uma classe em C++ o elemento bsico sobre o qual toda orientao por objetos est apoiada. Em
primeira instncia, uma classe uma extenso de uma estrutura, que passa a ter no apenas dados, mas
tambm funes. A idia que tipos abstratos de dados no so definidos pela sua representao interna, e
sim pelas operaes sobre o tipo. Ento no h nada mais natural do que incorporar estas operaes no
prprio tipo.Estas operaes s fazem sentido quando associadas s suas representaes.
No exemplo da calculadora, um candidato natural a se tornar uma classe a pilha. Esta uma
estrutura bem definida; no seu header file esto tanto a sua representao (struct Stack) quanto as funes
para a manipulao desta representao. Seguindo a idia de classe, estas funes no deveriam ser
globais, mas sim pertencerem estrutura Stack. A funo empty seria uma das que passariam para a
estrutura. A implementao de empty pode ficar dentro da prpria estrutura:
struct Stack {
// ...
int empty() { return top == 0; }
};
ou fora:
struct Stack {
// ...
int empty();
};
int Stack::empty(void) { return top == 0; }
No segundo caso a declarao fica no header file e a implementao no .c. A diferena entre as duas
opes ser explicada na seo sobre funes inline.
Com esta declarao, as funes so chamadas diretamente sobre a varivel que contm a
representao:
void main(void)
{
struct Stack s;
s.empty();
}
Repare que a funo deixou de ter como parmetro uma pilha. Isto era necessrio porque a funo
estava isolada da representao. Agora no, a funo faz parte da estrutura. Automaticamente todos os
campos da estrutura passam a ser visveis dentro da implementao da funo, sem necessidade se
especificar de qual pilha o campo top deve ser testado (caso da funo empty). Isto j foi dito na chamada
da funo.
Traduzindo estas definies para o C++, classes so estruturas, objetos so variveis do tipo de
alguma classe (instncia de alguma classe), mtodos so funes de classes e enviar uma mensagem para
um objeto chamar um mtodo de um objeto.
Resumindo:
Objetos so instncias de classes que respondem a mensagens de acordo com os mtodos e
atributos, descritos na classe.