qualidade de sw

download qualidade de sw

of 9

description

material de estudo

Transcript of qualidade de sw

Captulo 1

Captulo 1

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.

Fatores de qualidade externa

Corretude

a condio do programa de produzir respostas adequadas e corretas cumprindo rigorosamente suas tarefas de acordo com sua especificao.

Obviamente, uma qualidade primordial. Se um sistema no faz o que ele foi proposto a fazer, ento qualquer outra questo torna-se irrelevante.

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.

Modularidade - qualidade interna

Alguns fatores apresentados na seo anterior podem ser beneficiados com o uso de orientao por objetos. So eles: corretude, robustez, extensibilidade, reuso e compatibilidade. Estes refletem as mais srias questes para o desenvolvimento de programas. A medida que se olha para estes cinco aspectos, dois subgrupos surgem:

Extensibilidade, reuso e compatibilidade demandam arquiteturas que sejam flexveis, design descentralizado e a construo de mdulos coerentes conectados por interfaces bem definidas.

Corretude e robustez so favorecidos por tcnicas que suportam o desenvolvimento de sistemas baseados em uma especificao precisa de requisitos e limitaes.

Da necessidade da construo de arquiteturas de programas que sejam flexveis, surge a questo de tornar os programas mais modulares.

Uma definio precisa para modularidade dificilmente encontrada. No entanto, esta tcnica no traz benefcios se os mdulos no forem autonmos, coerentes e organizados em uma estrutura robusta. Ser utilizado no decorrer deste texto um conjunto de cinco critrios e cinco princpios.

Critrios para modularidade

Seguem abaixo cinco critrios que ajudam a avaliar/construir a modularidade do design:

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:

Decomposio: Se pretende-se dividir o desenvolvimento do sistema em tarefas separadas, cada uma destas deve resultar em uma unidade sinttica bem delimitada. (compilveis separadamente no caso de linguagens de programao)

Composio: S pode-se combinar coisas como unidades bem delimitadas.

Proteo: Somente pode haver controle do efeito de erros se os mdulos esto bem delimitados.

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?

Ocultao de informao (information hiding)

A aplicao deste princpio assume que todo mdulo conhecido atravs de uma descrio oficial e explcita; ou melhor sua interface. Pela definio, isto requer que haja uma viso restrita do mdulo.

Toda informao sobre um mdulo deve ser oculta (privada) para outro a no ser que seja especificamente declarada pblica.

A razo fundamental para este princpio o critrio de continuidade. Se um mdulo precisa ser alterado, mas de maneira que s haja manuteno de sua parte no pblica e no a interface; ento os mdulos que utilizam seus recursos (clientes) no precisam ser alterados. Alm, quanto menor a interface, maiores as chances de que isto ocorra.

Apesar de no haver uma regra absoluta sobre o que deve ser mantido pblico ou no, a idia geral simples: a interface deve ser uma descrio do funcionamento do mdulo. Tudo que for relacionado com sua implementao no deve ser pblico.

importante ressaltar que, neste caso, este princpio no implica em proteo no sentido de restries de segurana. Embora seja invisvel, pode haver acesso s informaes internas do mdulo.

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 #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 #include #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;}

/* a funo main fica em um loop lendo do teclado os comandos da calculadora. Se for um nmero, apenas empilha. Se for um operador, faz o calculo. Se for o caracter 'q', termina a execuo. Aps cada passo a pilha mostrada. */int main(void){ struct Stack* s = createStack(); while (1) { char str[31]; int i; printf("> "); gets(str); if (sscanf(str, "%d", &i)==1) push(s, i); else { int n1, n2; char c; sscanf(str, "%c", &c); switch(c) { case '+': if (getop(s, &n1, &n2)) push(s, n1+n2); break; case '-': if (getop(s, &n1, &n2)) push(s, n1-n2); break; case '/': if (getop(s, &n1, &n2)) push(s, n1/n2); break; case '*': if (getop(s, &n1, &n2)) push(s, n1*n2); break; case 'q': return 0; default: printf("error\n"); } } { int i; for (i=0; itop; i++) printf("%d:%6d\n", i, s->elems[i]); } }}

Tipos abstratos de dados

O conceito de tipo foi um passo importante no sentido de atingir uma linguagem capaz de suportar programao estruturada. Porm, at agora, no possvel usar uma metodologia na qual os programas sejam desenvolvidos por meio de decomposies de problemas baseadas no reconhecimento de abstraes. Para a abstrao de dados adequada a este propsito no basta meramente classificar os objetos quanto a suas estruturas de representao; em vez disso, os objetos devem ser classificados de acordo com o seu comportamento esperado. Esse comportamento expressado em termos das operaes que fazem sentido sobre esses dados; estas operaes so o nico meio de criar, modificar e se ter acesso aos objetos.

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.

O paradigma da orientao a objetos

Esta seo apresenta cinco componentes chave do paradigma de orientao por objetos. As componentes so objeto, mensagem, classe, instncia e mtodo. Eis as definies:

Objeto: uma abstrao encapsulada que tem um estado interno dado por uma lista de atributos cujos valores so nicos para o objeto. O objeto tambm conhece uma lista de mensagens que ele pode responder e sabe como responder cada uma. Encapsulamento e abstrao so definidos mais frente.

Mensagem: representada por um identificador que implica em uma ao a ser tomada pelo objeto que a recebe. Mensagens podem ser simples ou podem incluir parmetros que afetam como o objeto vai responder mensagem. A resposta tambm influenciada pelo estado interno do objeto.

Classe: um modelo para a criao de um objeto. Inclui em sua descrio um nome para o tipo de objeto, uma lista de atributos (e seus tipos) e uma lista de mensagens com os mtodos correspondentes que o objeto desta classe sabe responder.

Instncia: um objeto que tem suas propriedades definidas na descrio da classe. As propriedades que so nicas para as instncias so os valores dos atributos.

Mtodo: uma lista de instrues que define como um objeto responde a uma mensagem em particular. Um mtodo tipicamente consiste de expresses que enviam mais mensagens para objetos. Toda mensagem em uma classe tem um mtodo correspondente.

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.

Exerccio 1 - Calculadora RPN com classes

Transformar a pilha utilizada pela calculadora em uma classe.