Você está na página 1de 85

26-01-2010 name

Sebenta de
Desenvolvimento de
Software

Jos Coelho, 2007

Stio: Universidade Aberta


Unidade curricular: Desenvolvimento do Software 08/09
Livro: Sebenta de Desenvolvimento de Software
Impresso por: Jos Pedro Coelho
Data: Tera, 26 Janeiro 2010, 15:50

www.moodle.univ-ab.pt//print.php?id 1/85
26-01-2010 name

ndice
1 - Introduo
2 - Especificao
3 - Desenho
4 - Cdigo
5 - Testes
6 - Testes Empricos com o Engine Tester
7 - Instalao e Manuteno

www.moodle.univ-ab.pt//print.php?id 2/85
26-01-2010 name

1 - Introduo
A presente sebenta um texto sobre Desenvolvimento de Software, o qual deve ser complementado
pela utilizao de um ambiente de desenvolvimento avanado, sendo o Visual C++ 2008 Express Edition
o ambiente de desenvolvimento adoptado. Os textos desta sebenta so na sua maioria baseados no livro
de texto na bibliografia opcional.

O nosso objectivo nesta unidade curricular no conseguir desenvolver software, encontrar a melhor
maneira de o fazer, de forma a minimizar os custos e maximizar a qualidade do software, e porque no,
maximizar o prazer de o desenvolver. Este texto acompanhado de exemplos concretos, para assim
auxiliar o estudante a assimilar o contedo dos textos.

A sebenta comea por dar uma introduo ao Desenvolvimento de Software, nomeadamente as


principais fases de desenvolvimento e problemas que se levantam em cada fase e alguns conceitos,
continuando no segundo captulo com algumas notas sobre requisitos e caractersticas de um bom
desenho. No terceiro captulo abordado um tema central, programar bem de forma a escrever e ler
facilmente cdigo. So enumerados um conjunto de vantagens tanto na edio como na navegao e no
debuguer do Visual C++ 2008 Express Edition, e apresentada uma norma de escrita de cdigo. O
quarto captulo trata da questo de encontrar falhas, enumerando-se diversos tipos de defeitos, vrias
abordagens de testes unitrios, de testes de integrao, e de performance, bem como abordagens para a
estimao do nmero de falhas por descobrir no cdigo. O quinto captulo descreve uma metodologia
para efectuar testes empricos utilizando o software Engine Tester, acompanhado de um laboratrio
tambm disponvel em vdeo. Finalmente o sexto captulo aborda a questo de instalao e manuteno,
descrevendo sucintamente o que deve ser feito de forma a colocar o sistema em produo, a ser utilizado
e mantido com sucesso.

1.1 Fases de Desenvolvimento


O desenvolvimento de software uma tarefa complexa, em qualquer uma das suas diferentes fases:
especificao; desenho; cdigo; teste; instalao; manuteno. uma tarefa complexa porque por um
lado longa, e por isso envolve normalmente vrias pessoas a trabalhar em simultneo, mas
principalmente porque fcil fazer-se algo errado, algo que no servir para nada, uma vez que no h
forma de se ter a certeza que o que est feito est bem feito.

1.1.1 Especificao e Desenho


Naturalmente que mesmo com estas condicionantes a especificao de uma aplicao de software tem
que ser feita, e ser feita bem. Caso a aplicao fique mal especificada, o erro poder vir a ser detectado
na melhor das hipteses na fase seguinte, no desenho, ou apenas na fase de codificao, e no pior caso
aps estas fases, provocando que ainda mais trabalho seja deitado fora.

Ser fcil fazer uma especificao bem feita? Desde que esta seja consistente, ou seja, que todas as suas
especificaes possam ser satisfeitas, e seja completa, ou seja, que todas as situaes estejam previstas,
ser certamente uma boa especificao. Necessita ainda que seja uma soluo para o problema que o
cliente pretende resolver, assumindo que o cliente conhece bem qual o problema que pretende resolver.
Para tal h ferramentas que auxiliam este processo, nomeadamente diagramas UML, e que so matria
da unidade curricular Anlise de Sistemas. Nesta unidade curricular esta matria abordada
superficialmente.

Assumindo que no h problemas na especificao, o desenho deve ser feito correctamente para que se
www.moodle.univ-ab.pt//print.php?id 3/85
26-01-2010 name
possa comear a escrever cdigo. O desenho deve especificar uma implementao concreta ao que
pedido pelo cliente, formalizado na fase anterior. Caso no implemente o que pedido, as restantes fases
vo ser feitas para nada. Na fase de teste, ou numa pior situao em que o cliente no est envolvido, na
fase de instalao, o cliente vem dizer que no era aquilo que pretendia e parte do trabalho deitado
fora. Os diagramas UML continuam aqui a ter um papel importante, sendo esta matria tambm da
unidade curricular Anlise de Sistemas. Nesta unidade curricular esta matria abordada
superficialmente.

Os materiais da especificao e desenho, bem como dos aspectos introdutrios de Desenvolvimento de


Software, so o 1, 2 e 3 captulos da sebenta. Como materiais complementares aconselha-se o livro
opcional, captulos 1, 4, 5 e 6.

1.1.2 Cdigo
Chegamos fase do cdigo, fase esta que confia que as fases anteriores foram feitas com a mxima
ateno. Qualquer erro nessas fases significa que o trabalho a iniciar agora poder no servir para nada.
Mas isso no seria problema, no fosse esta fase ter sempre uma certa incerteza associada: ser que
serei capaz de implementar o algoritmo especificado? Para alm disto h que conhecer a sintaxe da
linguagem de programao, as bibliotecas disponveis, a estrutura de dados e o algoritmo a implementar,
e o resto dos mtodos que sero implementados pelo prprio programador posteriormente, ou por um
colega. Ao programar um algoritmo complexo, o programador tem de ter em mente a estrutura de dados
e os seus valores a cada passo da execuo do algoritmo. uma tarefa em que o mais fcil errar, mas
felizmente nem sempre h algoritmos complexos, mas mesmo sem algoritmo complexo, o que necessita
de estar na mente do programador ao escrever cada linha de cdigo um volume considervel de
informao.

No h forma de se saber com certeza que o trabalho feito est correcto. Assim, pode-se ir avanando
na implementao de outras partes e ter que se voltar para trs ao descobrir que uma das partes no
funciona correctamente. Felizmente que a programao orientada por objectos permite modelar cdigo
de forma a tornar as diferentes partes do cdigo mais independentes, ou seja, caso um mdulo esteja
incorrecto, apenas tem que ser revisto o cdigo desse mdulo.

Qual o problema de se errar na fase do cdigo? No h problema, qualquer programador suposto


errar. No lhe pedido que faa cdigo sem erros dado que tal impossvel garantir. Mas isto no
significa que o programador possa no dar a sua mxima ateno ao escrever cdigo. A maior parte dos
erros leva a erros de compilao, ou seja, erros que provocam que o cdigo no seja aceite pelo
compilador como um cdigo vlido. Outros erros tornam os resultados completamente disparatados e
so apanhados nos testes preliminares que o programador deve fazer para ter alguma segurana que o
cdigo est a funcionar bem. Caso o programador no esteja na sua mxima ateno, ir aperceber-se
dos resultados disparatados e ao tentar identificar o que est de errado ir inserir erros pensando que
est a corrigir os resultados disparatados. Aps vrias iteraes para a frente e para trs, acaba por
conseguir uma verso que funciona. Estar essa verso isenta de erros? Certamente que no, apenas
passou os testes de utilizao normal que o programador j cansado fez. H outros erros no cdigo, que
no se evidenciam agora, apenas em situaes menos normais iro ficar activos, mas que podem mesmo
assim inviabilizar a usabilidade do sistema.

Este cenrio no nada agradvel para o programador, dir-se-ia que ningum gostaria de estar na pele
de um programador. No entanto as grandes dificuldades atraem pessoas que as fazem, pelo desafio e
pelo prazer de ver a dificuldade ultrapassada, e a programao no excepo. Existem hoje em dia
ferramentas para auxiliarem este processo, que so os Ambientes de Desenvolvimento Integrados, os
quais so de importncia capital em grandes projectos e com todo o mrito so matria desta unidade
www.moodle.univ-ab.pt//print.php?id 4/85
26-01-2010 name
curricular. Estas ferramentas no servem para que o programador no necessite saber fazer isto ou
aquilo, servem apenas para poupar na memria e na escrita que o programador necessita para escrever
cada linha de cdigo. natural que um programador que conhea bem o ambiente de desenvolvimento
que tem, no gastar tempo a ver as bibliotecas que tem disponveis, j as conhece, tendo uma
produtividade bastante mais elevada que outro que se inicia nesse ambiente de desenvolvimento.
Pretende-se nesta unidade curricular analisar um ambiente de desenvolvimento em concreto, Visual C++
2008 Express Edition, de forma a que o estudante conhea as principais funcionalidades que lhe
permitem programar de forma mais confortvel, sem necessidade de tanta memorizao e ateno,
resultando num aumento claro da sua produtividade.

Os materiais da fase do Cdigo, o 4 captulo da sebenta. Como materiais complementares aconselha-


se o livro opcional, captulo 7.

1.1.3 Teste
O cdigo aps implementado e testado pelo seu programador passa agora fase de testes, para poder
ser devidamente verificado por um colega. O objectivo do colega encontrar falhas no cdigo, e para tal
vai efectuar grande volume de testes na tentativa de encontrar falhas. Ao encontrar uma falha tem de a
poder repetir para que esta seja reportada, mas no tem que sequer olhar para o cdigo. Os testes so
feitos tanto a cada mdulo separadamente (testes unitrios), como ao conjunto dos mdulos (testes de
integrao). Esta actividade requer alguma imaginao e criatividade de forma a colocar o sistema
perante situaes novas, dado que repetir situaes normais em que o sistema funciona, de nada adianta
nos testes. Caso no exista essa imaginao e criatividade, apenas as falhas mais banais sero
identificadas, e as restantes ficaro por identificar. Sero alguma vez identificadas? Concerteza que sim,
pelo o utilizador do sistema, que tem normalmente sempre mais criatividade e imaginao para colocar o
sistema perante situaes no testadas.

Este trabalho no notoriamente algo que deva ser feito por quem acabou de escrever o cdigo.
Primeiro pelo cansao ao cdigo que j dever ter acumulado aps ter escrito o cdigo, e desta forma
no ter a dose de imaginao e criatividade necessrias, e segundo porque uma tarefa que se falhar tem
menos trabalho, e em terceiro porque uma tarefa que se falhar ningum d por isso. Naturalmente que
se detectar uma falha no deixar de a reportar. No entanto a falta de imaginao e criatividade do autor
do cdigo podem ser aqui determinantes. Alm disso, se um erro ou outro passar para os
utilizadores descobrirem, qual o problema para o programador? At d um certo gozo, dado que o
trabalho e a complexidade do cdigo que os programadores fazem normalmente desconhecido dos
utilizadores. Havendo um erro, o utilizador reconhece a sua total incompetncia e nem sequer l a
mensagem de erro porque considera partida que nunca a iria entender. Decididamente, no dever ser
o programador que escreveu o cdigo a fazer os testes.

Esta fase por vezes no executada. Porqu? O cdigo est escrito, h um responsvel pelo desenho,
no caso do sistema no corresponder ao que est na especificao assinada pelo cliente, e cada bloco de
cdigo foi escrito por um programador, que o responsvel pelo que fez. Para alm deste argumento h
tambm outros dois, talvez at de maior peso: a fase de testes aumenta o tempo e custo de
desenvolvimento de software. Ainda por cima cria um mal estar na empresa, colegas a fiscalizarem o
trabalho de colegas. Todo este tipo de argumentos so aceites apenas por quem no compreende a
impossibilidade de se fazer cdigo sem erros, e no considera normal que o cdigo tenha erros. Dever
ser feita a melhor tentativa para identificar e remover os erros enquanto a aplicao est na empresa,
caso contrrio sero encontrados fora da empresa com maiores custos no s em termos de tempo gasto
nos recursos humanos como tambm em termos da imagem da empresa. Esta matria desta unidade
curricular, onde ser utilizado um software de testes, o EngineTester.

www.moodle.univ-ab.pt//print.php?id 5/85
26-01-2010 name
Os materiais da fase de Teste, o 5 e 6 captulo da sebenta e os vdeos de demonstrao do Engine
Tester. Como materiais complementares aconselha-se o livro opcional, captulos 8 e 9.

1.1.4 Instalao e Manuteno

Aps desenvolvido e testado o software, este tem de ser entregue ao seu destinatrio final, o cliente. O
software ser instalado e utilizado pelos utilizadores sem problemas, e funcionar para sempre, gastando
apenas energia elctrica? Infelizmente no ser assim. Os utilizadores iro tentar utilizar o software de
acordo com o que acham que este deve de ser, e caso o software no faa o que pretendem,
consideram que no funciona e deixam de o utilizar. Caso o software sobreviva ao tempo, ser
reinstalado vrias vezes, quer por actualizao de hardware, quer por actualizao de sistema operativo.
Sero encontrados erros, ser necessrio implementar novas funcionalidades, mas as pessoas que
desenvolveram o software podem j no estar a trabalhar na empresa.

Muitas so as situaes que levam a que o software deixe de ser utilizado. As ltimas fases no
desenvolvimento de software so determinantes para a longevidade deste, e portanto a sua rentabilidade.
Como lidar com as situaes expostas no pargrafo anterior? Simplesmente com o recurso boa
documentao, e nos sistemas mais complexos e essenciais, alocao permanente de recursos humanos
para a manuteno do sistema.

A documentao deve existir a todos os nveis: interna no prprio cdigo; externa ao cdigo mas tcnica;
documentao para o utilizador. destinada a poupar o tempo de quem a l, seja o utilizador para poder
utilizar o sistema, seja o programador (o prprio que desenvolveu o cdigo ou um colega) para poder
compreender o cdigo e corrigir um bug, ou implementar uma nova funcionalidade.

No entanto a documentao normalmente muito pobre. Os manuais de utilizador ningum os l. Quem


l s v frases bvias, pelo que desiste de ler e vai mas utilizar o programa directamente. Outros
utilizadores ao lerem o manual no percebem nada, e por vezes antes mesmo de ler pedem logo a algum
que lhe explique o que o manual quer dizer. A documentao tcnica normalmente escrita de forma a
que apenas o prprio programador a compreende, isto se a ler logo aps a ter escrito. Perde-se tempo a
escrever documentao de utilidade duvidosa, e quem a escreve pensa por vezes que um trabalho que
qualquer um pode fazer, ao contrrio da programao, essa sim, uma actividade difcil. Quando o tempo
no existe, tanto devido a presses do chefe que considera j inaceitvel o tempo que est a levar para
escrever um pequeno bloco de cdigo, como devido ao facto de que apenas os maus programadores
levam muito tempo a programar, a documentao algo que normalmente aligeirado.

As tendncias para que a documentao no exista ou seja de m qualidade devem ser combatidas, caso
contrrio o software poder rapidamente deixar de ser utilizado, ou nunca chegar a ser utilizado. Este
problema aumenta em projectos que necessitem de equipas de desenvolvimento de software. Os
diferentes programadores no vo estar permanentemente em reunies a falar sobre o cdigo. O grosso
da comunicao feita atravs da documentao tcnica, que deve estar em boas condies para ser
facilmente compreendida por quem a l, seja por um colega no dia seguinte, seja pelo prprio
programador daqui a um ano. Nesta unidade curricular esta matria abordada superficialmente.

Um projecto feito por um conjunto de ficheiros que vai sendo editado ao longo do tempo pela equipa
de desenvolvimento. Quando se tem vrias pessoas a editar os mesmos ficheiros, pode haver situaes
em que o mesmo ficheiro esteja a ser editado em simultneo por duas pessoas, levando a que as
alteraes feitas pela primeira pessoa a gravar sejam perdidas. Vrias outras situaes indesejadas
podem ocorrer, por exemplo, algum acidentalmente apaga um ou mais ficheiros do projecto. Para que
se possa trabalhar em equipa, necessrio um sistema de controlo de verses, que impede que situaes
destas ocorram.

www.moodle.univ-ab.pt//print.php?id 6/85
26-01-2010 name
Os materiais da fase de Instalao e Manuteno, o 7 captulo da sebenta. Como materiais
complementares aconselha-se o livro opcional, captulos 10 e 11.

1.2 Conceitos
Nesta seco descrevem-se alguns conceitos soltos de Desenvolvimento de Software.

1.2.1 Engenharia de Software


Engenharia de software a rea que desenha e implementa solues de um problema, utilizando para tal
computadores e linguagens de programao como meios para atingir os fins pretendidos.

Nem todos os problemas passam por solues informticas. H que analisar o problema e subproblemas
envolvidos e suas relaes, e construir uma soluo. Os problemas surgem da necessidade de melhoria
dos processos que decorrem numa empresa e na sua maioria as solues envolvem informtica.

Processos que utilizam muito papel podem ser aligeirados pela informatizao de parte do processo,
simplesmente por mudar o suporte de parte da documentao para ficheiros em disco e numa segunda
fase para base de dados.

Um processo que requeira comunicao intensa entre pessoas pode tambm ser aligeirada com o simples
aumento do uso do email em vez do telefone, e numa segunda fase um sistema informtico que tenha o
processo implementado, passando o processo automaticamente pelas pessoas que o devem analisar.

Em ambos os exemplos, na primeira soluo no so necessrios engenheiros informticos, embora se


utilize informtica, uma vez que apenas h necessidade de se utilizar email e/ou sistema de ficheiros que
pode ser configurado por um tcnico de informtica, e ser dada formao s pessoas que dela
necessitem. Na segunda soluo necessrio implementar um sistema informtico especfico de raiz, ou
mesmo que se utilize uma soluo global, esta necessita sempre de ser desenhada e customizada por
engenheiros informticos.

1.2.2 Erro / Defeito / Falha

Um erro uma falha humana, relativamente ao que era suposto fazer-se.

Um defeito uma consequncia do erro no cdigo (ou especificao / desenho) que assim ir funcionar
de forma defeituosa. Um defeito ir acontecer aps um erro, se quem cometer o erro no der por isso.

Um defeito pode ou no ter consequncias finais. No caso de ter, ir provocar uma ou mais falhas no
sistema, que so uma no conformidade do sistema com os requisitos.

Exemplos:

Um programador pode esquecer-se de declarar uma varivel. Este erro no teria no entanto
grandes consequncias, j que seria detectado em tempo de compilao, e seria de imediato
corrigido.
Um programador poder declarar uma varivel do tipo real (double) quando deveria ser do tipo
inteira (int). Neste caso o erro passaria a defeito, mas sem consequncias de maior dado que um
double pode guardar todos os valores de inteiros. Se no entanto o cdigo tiver divises
supostamente inteiras, neste caso seriam feitas divises reais, e o defeito poderia passar a falha,
sendo visvel para o utilizador.

www.moodle.univ-ab.pt//print.php?id 7/85
26-01-2010 name
Os ambiente de desenvolvimento modernos (exemplo do Eclipse e Vistual Studio), tm tendncia a evitar
erros ao completar parte do cdigo automaticamente, e a levar o programador a detectar imediatamente
erros ao colorir parte do cdigo e sublinhar o cdigo suspeito. Assim diminui-se o nmero de defeitos.

A filosofia do Visual Basic no sentido de permitir os tipos de erros mais comuns, e no obrigar o
programador a grande escrita. Desta forma diminui o nmero de defeitos, mas permite de igual forma
alguns defeitos que o programador detectaria caso fosse obrigado a maior detalhe no cdigo. A no
obrigatoriedade de declarar variveis e o no distinguir minsculas de maisculas, deixam passar defeitos
que no passam em outras linguagens.

Os defeitos que passam desapercebidos, alguns nem tanto uma vez que resultam em alertas de
compilador muitas vezes ignorados pelo programador, no so tipicamente simples de descobrir
por leitura atenta do cdigo. Com o evoluir dos ambientes de desenvolvimento estes defeitos ficam
restritos aos que tm baixa frequncia de ocorrncia, e no existe nada que os detecte seno uma fase de
teste feita correctamente, e mesmo assim nada garantido.

1.2.3 Participantes
Existem basicamente trs participantes no desenvolvimento de software: o cliente, o utilizador e o
programador. O cliente quem paga pelo sistema, o utilizador quem usa o sistema e o programador
quem implementa o sistema. Estes participantes tanto podem ser uma s pessoa como vrias pessoas ou
uma organizao. Nem sempre so entidades distintas, num caso limite so uma s pessoa, no caso de
um programador fazer um programa para ele prprio utilizar.

Esta diviso til para ver os diversos pontos de vista. O cliente que tem o problema que necessita de
ser resolvido, no vale a pena resolver um outro problema que no seja o do cliente. O utilizador que
vai utilizar o sistema, ou seja a soluo, e deve conseguir faz-lo, no vale a pena fazer o sistema se os
utilizadores a que se destina no o conseguirem utilizar. O programador que tem que desenvolver o
sistema, no deve deixar nenhuma das fases que lhe pertencem para o utilizador fazer, como por exemplo
o teste do sistema.

1.2.4 Membros da Equipa


No tpico anterior o programador representa todos os membros da equipa de desenvolvimento de
software, mas dependendo da fase h diversos participantes:

Definio de Requisitos - participa o Analista - tem que saber o que o cliente quer;
Desenho do Sistema - participa o Desenhador, e o Analista - descrio do sistema de acordo com
os requisitos;
Desenho do Programa - participa o Desenhador, e o Programador - descrio detalhada;
Implementao - participa o Programador;
Teste de Unidades - participa o Programador, e o Tester - testes de cada unidade implementada;
Teste de Integrao - participa o Tester - testes das diferentes unidades em conjunto;
Teste do Sistema - participa o Tester - teste de todo o sistema;
Instalao / Entrega - participa o Instrutor - mostrar/formar utilizadores do sistema;
Manuteno - participa o Instrutor - corrigir problemas que ocorram.

H que ter em ateno que a dimenso do projecto pode justificar ou no a existncia de determinadas
fases, podendo tambm a mesma pessoa desempenhar diversos papeis. No caso limite, se a equipa de
desenvolvimento de software tiver apenas uma pessoa, esta desempenha todos os papeis. no entanto
conveniente que as diversas fases sejam feitas por pessoas diferentes, de forma a que umas possam
verificar o trabalho das outras.
www.moodle.univ-ab.pt//print.php?id 8/85
26-01-2010 name
verificar o trabalho das outras.

Manda o bom senso que se atribua s pessoas com maior experincia as primeiras fases, j que as fases
seguintes esto normalmente dependentes das anteriores. Algo mal feito numa fase inicial pode
condicionar muito mais que algo mal feito nas ltimas fases.

Mais informao:
http://pt.wikipedia.org/wiki/Engenharia_de_Software
"Software Engineering, theory and practice", second edition,
Prentice Hall, Shari Pfleeger, pg. 2-4, 6, 14-15, 25-27, 136, 141,
145

www.moodle.univ-ab.pt//print.php?id 9/85
26-01-2010 name

2 - Especificao
Este captulo aborda superficialmente a fases da Especificao, e o captulo seguinte Desenho. Estas
matrias so abordadas com o devido detalhe na unidade curricular de Anlise de Sistemas.

Um requisito uma funcionalidade ou caracterstica que o sistema tem de possuir. O conjunto de


requisitos do sistema define o que o cliente pretende. essencial que estes sejam verificados pelo cliente
para evitar que se implemente um sistema diferente do pretendido.

Um requisito diz-se funcional se se refere a uma interaco entre o sistema e o exterior, definindo o
procedimento que o sistema deve fazer para uma ou mais situaes. Exemplos: registar todas as entradas
e sadas de dados num ficheiro; ter um campo de observaes para cada registo de uma lista de
contactos; devolver o valor da expresso matemtica que o utilizador introduzir; apresentar a pgina
seguinte de texto, aps o utilizador ter carregado na tecla PgDn.

Um requisito diz-se no funcional se impor apenas uma restrio ao sistema, no definindo nenhuma
procedimento concreto. Exemplos: impor um tempo de resposta mximo para determinadas situaes;
forar um sistema operativo ou um determinado computador.

Os requisitos so inconsistentes caso no exista possibilidade de serem todos satisfeitos em simultneo.


Por exemplo, um requisito diz que, para um conjunto de 10 ecrans sucessivos no preenchimento de um
formulrio, um utilizador poder levar entre 10 e 30 segundos em cada ecran, enquanto que outro
requisito diz que o sistema dever abortar caso o utilizador no termine o formulrio aps 60 segundos.
Para cumprir o ltimo requisito, os utilizadores teriam de preencher cada ecran em menos de 10
segundos, o que contraria o primeiro requisito.

Os requisitos so completos caso todas as situaes em que o sistema possa vir a estar tiverem um
procedimento definido. Por exemplo, a definio de uma funo factorial, que recebe um inteiro natural,
pode deixar de fora o caso do factorial de zero. Embora esta funo possa no vir a ser chamada com
este argumento, pode ser complicado demonstrar que essa situao no ir ocorrer, pelo que estipulando
o valor de retorno nessa situao garante que os requisitos ficam completos.

Os requisitos devem ser realistas e verificveis. Um requisito impossvel na tecnologia actual, no pode
ser implementado, e um requisito que no se possa verificar, provavelmente nunca ficaria bem
implementado devido a no poder ser testado convenientemente.

Para se conseguir uma boa especificao necessrio conseguir comunicar com o cliente. Primeiro
conseguir compreender o problema do cliente. Segundo, conseguir transmitir a soluo proposta ao
cliente. Normalmente a linguagem tcnica no a melhor forma de o fazer, muito embora seja
normalmente a mais fcil. A utilizao de diagramas UML so aqui de grande utilidade, em complemento
a uma lista de requisitos. Embora o cliente possa vir a validar a especificao de requisitos, provvel
que no saiba se a soluo proposta resolve o seu problema. da responsabilidade do analista certificar-
se que a soluo que prope resolve o problema do cliente.

Por vezes h uma inverso de papeis nesta fase. O cliente pode at nem sequer falar do seu problema e
apresentar ao analista o que pretende que se faa, a soluo, na sua prpria linguagem, sendo afinado
pelo analista de forma a fazer sentido. Tal no ser aceitvel a no ser que o cliente tenha competncias
para tal. Se no tiver competncias o mais provvel que o que pede no ser soluo do seu problema.
Ser implementado e haver seguramente mais iteraes do tipo: " necessrio tambm isto, caso
contrrio isto tudo no faz sentido". Fica um projecto condenado a custar muito mais, tanto no
preo como na pacincia, isto apenas para que o analista no ponha em causa as capacidades
www.moodle.univ-ab.pt//print.php?id 10/85
26-01-2010 name
informticas do cliente.

Exemplo: Poker

Vamos colocar um exemplo concreto para utilizar ao longo da sebenta.

Especificao A:

1. Pretende-se um sistema para simular jogos de poker entre quatro jogadores, com 7
cartas, com 2 cartas fechadas e 5 abertas (ver:
http://en.wikipedia.org/wiki/Texas_hold_%27em).
2. Pretende-se para cada jogo obter a melhor mo de cada jogador.

Quem j tenha jogado poker, provavelmente a especificao a cima suficiente. No entanto h diversos
conceitos indefinidos na frase acima, alguns dos quais so de conhecimento geral, outros nem tanto.
sempre conveniente que na especificao seja especificado tudo com clareza, mesmo conceitos do
conhecimento geral. Por exemplo, quem nunca tiver jogado poker, poder no saber qual o baralho que
se utiliza, e quem nunca tiver jogado cartas, poder no saber que um jogo de cartas implica a utilizao
e um baralho. Os conceitos de cartas fechadas e abertas, no s esto relacionados com o jogo, pelo
que requerem conhecer-se o jogo, como pode eventualmente existir mais que uma denominao para o
mesmo conceito. Finalmente, nem sequer referido que mos existem, nem a sua ordem de valor.

Se tanto o analista como o cliente se entendem atravs de uma especificao do nvel desta, valer a
pena maior formalizao? Vale concerteza, j que o risco envolvido aceitando uma especificao deste
tipo muito elevado. O cliente poder nem ter conscincia do que est a pedir, e muito provavelmente o
analista tambm no sabe o que est a aceitar. Para alm disso, se houver conflitos esta especificao de
nada serve, cada parte ir elaborar a interpretao que lhe interessar.

Esta poderia ter sido a primeira interaco do analista com o cliente, vamos reflectir um pouco sobre a
especificao em outra prespectiva. Quem o cliente? Eventualmente um jogador de poker, ou um
casino. Qual o problema que o jogador de poker quer resolver? Ser realmente a simulao de jogos
de poker? Provavelmente no, j que no tem ganho directo por ver um jogo simulado, dado que
quando estiver a jogar o jogo no ser o mesmo. O que o cliente quer muito provvelmente informao
til que possa utilizar durante um jogo de poker, pelo que esta especificao ir certamente evoluir.
Como para obter informao til num jogo de poker ser necessrio simular jogos de poker, no vale a
pena complicar a especificao com a informao que se pretende extrair atravs dos jogos simulados.

Outro ponto a ter em ateno na especificao a introduo de constantes. Neste caso, o jogo
jogado entre 4 jogadores, com mos de 7 cartas, com 5 cartas abertas, 2 cartas fechadas. neste
problema que o cliente est interessado, no entanto no h grande ganho em utilizar esta informao
como constantes, e o prprio cliente facilmente poder mudar de ideias e espera que a mudana seja
simples, pelo que, a no ser que exista uma vantagem bvia, as constantes devem ser tratadas como
parmetros, tendo naturalmente os valores iniciais que o cliente especificou. Desta forma estamos a
aumentar a reusabilidade do cdigo.

Especificao B:

1. Utilizar um baralho de 52 cartas (4 naipes e 13 nmeros:


2;3;4;5;6;7;8;9;10;V;D;R;A), e baralhar de forma a distribuir cartas de forma
aleatria por NJ=4 jogadores (1<NJ<8);
2. Distribuir cartas, colocando CA=5 cartas na mesa, e CF=2 cartas em cada um de
quatro jogadores (as primeiras CA+NJ*CF=13 cartas do baralho; 0<=CA<=5;

www.moodle.univ-ab.pt//print.php?id 11/85
26-01-2010 name
0<CF<=5; 5<=CA+CF<=7);
3. Analisar as cartas de cada jogador juntamente com as duas cartas na mesa, e
calcular a melhor mo;
4. A mo mais alta a sequncia e cr real, em que consiste em 5 cartas todas do
mesmo naipe, com os 5 nmeros mais altos (10;V;D;R;A);
5. A segunda mo a sequncia e cr, em que consiste em 5 cartas todas do mesmo
naipe, com 5 nmeros seguidos;
6. A terceira mo o poker, em que consiste em 4 cartas com o mesmo nmero;
7. A quarta mo o fullen, em que consiste em 3 cartas com o mesmo nmero, e outras
2 cartas com o mesmo nmero;
8. A quinta mo a cr, em que consiste em 5 cartas todas do mesmo naipe;
9. A sexta mo a sequncia, em que consistem em 5 cartas com nmeros seguidos;
10. A stima mo o trio, em que consiste em 3 cartas com o mesmo nmero;
11. A oitava mo so dois pares, em que consiste em 2 cartas com o mesmo nmero, e
outras duas cartas com o mesmo nmero;
12. A nona mo o par, em que consiste em 2 cartas com o mesmo nmero;
13. A dcima mo nada, quando no existe nenhuma outra mo;
14. Se duas mos forem iguais, a mo com a carta mais alta a melhor.

Nesta especificao j no h grandes conceitos omissos, excepto o conceito de naipe e nmero, que
para quem nunca tenha visto um baralho pode ser confuso. tambm uma especificao mais longa, pelo
que poder no ser lida com a mesma ateno que a primeira especificao. sempre conveniente
colocar o mais importante primeiro, de forma a aproveitar no s a maior ateno do leitor, como para
ser sempre clara a utilidade de cada requisito.

A passagem de constantes para variveis fora a especificar o domnio das variveis. Como no faz parte
da especificao inicial do cliente, convm colocar domnios que no causem problemas, nem
compliquem o resto da especificao, caso contrrio perde-se a vantagem de passagem das constantes
para variveis. Por exemplo, ao no incluir a restrio 5<=CA+CF poderia acontecer que para cada
jogador existissem menos de 5 cartas, enquanto que as mos so vistas em grupos de 5 cartas. Teriamos
de definir o que acontece para esses casos, e estariamos provavelmente a seguir por um caminho bem
distante do que o cliente pretende.

Especificao C

1.
2.
3.
4.
5.
6.
7.

8.

www.moodle.univ-ab.pt//print.php?id 12/85
26-01-2010 name

9.

10.

11.

12.

13.

14.

15.

16.
17.

18.

19.

20.
21.
22.
23.
24.

At que frmula leu antes de passar para esta linha? Se leu todas as frmulas, certamente um entre
poucos que se sente vontade na matemtica. Esta linguagem pode no ser a melhor forma de
comunicar com o cliente, no entanto, este problema tem uma especificao complexa, e dado o
background do cliente, jogador de poker, provvel que se sinta vontade na matemtica, e desta
www.moodle.univ-ab.pt//print.php?id 13/85
26-01-2010 name
forma fica claro o trabalho envolvido, que tem que ser pago e reconhecido em conformidade.

Vamos percorrer as frmulas e comentar, construindo o que poderia ser uma segunda verso da
especificao C para um cliente adverso matemtica:

1. A numerao a seguinte: 2,3,4,5,6,7,8,9,10,V,D,R,A


2. Existem os seguintes naipes: P,O,C,E
3. Um baralho constitudo por 52 cartas, cada uma identificada por um nmero e naipe nicos;
4. So analisadas mos (conjuntos) de 5 cartas;
5. As cartas so baralhadas, ficando por uma ordem aleatria;
6. Cada um dos jogadores pode contar com as primeiras CA=5 cartas abertas (ficam na mesa), e
com CF=2 cartas fechadas (apenas suas), distribudas por ordem a cada jogador;
7. Os nmeros tm uma ordem de valor, sendo 2 o mais baixo e A o mais alto;
8. Uma mo de 5 cartas SCR (sequncia cor real) se tiver os 5 nmeros mais altos e todas as
cartas forem do mesmo naipe (cor);
9. Uma mo de 5 cartas SC (sequncia e cor) se tiver os 5 nmeros seguidos e todas as cartas
forem do mesmo naipe, e no SCR;
10. Uma mo de 5 cartas Poker se tiver quatro cartas com o mesmo nmero;
11. Uma mo de 5 cartas Fullen se tiver trs cartas com o mesmo nmero e outras duas cartas com
o mesmo nmero;
12. Uma mo de 5 cartas Trio se tiver trs cartas com o mesmo nmero e no for Fullen nem Poker;
13. Uma mo de 5 cartas Dois Pares se tiver duas cartas com o mesmo nmero e outras duas cartas
com o mesmo nmero, e no for Fullen nem Poker;
14. Uma mo de 5 cartas Par se tiver duas cartas com o mesmo nmero e no for Dois Pares, Trio,
Poker nem Fullen;
15. Uma mo de 5 cartas Cor se tiver cinco cartas todas do mesmo naipe, e no for SCR nem SC;
16. Uma mo de 5 cartas Sequncia se tiver cinco cartas com os nmeros seguidos, e no for SCR
nem SC;
17. Uma mo de 5 cartas Nada se no for nenhuma das mos anteriormente definidas;
18. Existem apenas os tipos de mos definidos anteriormente: SCR, SC, Poker, Trio, 2Pares, Par,
Fullen, Cor, Sequncia, Nada;
19. A funo TipoMo, para uma mo de 5 cartas retorna o tipo dessa mo;
20. (definio da funo TipoMo)
21. A relao MelhorMo, para duas mos de 5 cartas A e B, identifica se A melhor que B. A
melhor que B se de um tipo de mos menos frequente, ou no caso de serem do mesmo tipo, tem
a carta com o nmero mais alto;
22. (definio da relao MelhorMo)
23. Cada jogador deve seleccionar de entre as cartas que pode contar, uma mo de 5 cartas;
24. A mo de 5 cartas seleccionadas, deve ser a melhor de entre as mos disponveis para o jogador.

A utilidade dos diagramas UML nesta fase reduzida para este exemplo, dado que um simulador, e
no h grandes interaces com o utilizador, este apenas manda o simulador correr e v o resultado.

Estes requisitos so todos funcionais, um exemplo de um requisito no funcional seria forar a linguagem
de programao a ser C++. So tambm consistentes, mas facilmente se poderia ter colocado requisitos
inconsistentes, logo no requisito 3, no caso de haver um erro no nmero de cartas no baralho, se este
fosse superior a 52 seria impossvel de utilizar o nmero e naipe para identificar cada carta, dado que h
13 nmeros e 4 naipes. Estes requisitos no so provavelmente completos, ao contrrio do que seria
ideal. No esto definidas situaes que possibilitem sempre escolher a melhor mo de qualquer conjunto
de cartas. Por exemplo, se o conjunto de cartas todo o baralho, o melhor tipo de mo SCR,
existindo 4 mos possveis, de igual valor (uma sequncia cr real de cada naipe), pelo que fica indefinido
www.moodle.univ-ab.pt//print.php?id 14/85
26-01-2010 name
que mo deve ser escolhida nessa situao.

O cliente disse o que queria, tempo do analista propr uma soluo, que o que ser feito na fase
seguinte.

www.moodle.univ-ab.pt//print.php?id 15/85
26-01-2010 name

3 - Desenho
Atravs de desenhos podem-se representar a duas dimenses objectos reais, pessoas, paisagens,
mapas, etc. Esses desenhos tm informao sobre as entidades que representam. Assim tambm o
desenho em informtica, mas destina-se a representar um sistema informtico, podendo ser feito a vrios
nveis de detalhe.

O cdigo no pode ser comeado a escrever aps a especificao de requisitos. Primeiro necessrio
fazer o desenho do sistema para se saber que cdigo necessrio desenvolver.

3.1 Desenho Conceptual e Tcnico


Aps os requisitos definidos, h que transform-los num sistema funcional. O desenho conceptual ou
desenho do sistema esse sistema na linguagem do cliente. Aps o cliente aprovar o desenho conceptual
pode-se produzir o desenho tcnico ou desenho do programa, que define em termos tcnicos como vai
ser implementado o sistema.

O sistema anterior aparentemente simples, na verdade um processo iterativo. A construo do desenho


conceptual e tcnico dependente dos requisitos, podendo estes serem revistos caso se encontrem
inconsistncias ou lacunas. O cliente pode tambm rever as suas necessidades ao analisar o desenho
conceptual e compreender melhor o seu prprio problema e soluo apontada, bem como o analista ao
construir o desenho tcnico pode se ver obrigado a alterar o desenho conceptual.

3.2 Construo do Desenho


Wasserman em 1995 sugere a construo do desenho em uma das seguintes formas:

Decomposio Modular - atribui funes a componentes ou mdulos, comeando pelas funes


que o sistema tem de suportar;
Decomposio Orientada nos Dados - baseia-se na estrutura de dados;
Decomposio Orientada nos Eventos - baseia-se nos eventos recebidos pelo sistema, e como
estes devem ser tratados;
Desenho baseado na Interface - mapeia toda a interaco do utilizador com o sistema, e tudo o
que o sistema deve fazer com essa interaco;
Desenho Orientado a Objectos - identifica as classes de objectos que o sistema tem, suas relaes
e atributos.

Actualmente a programao orientada a objectos dominante, pelo que estas estratgias podem-se
fundir numa s, tendo em ateno que uma classe deve: ter uma funo clara no sistema (decomposio
modular); assentar numa estrutura de dados tambm bem definida (decomposio orientada nos
dados); os eventos ou mtodos que trata devem ser claros e naturais relativamente funo principal que
implementa.

A programao orientada a objectos apenas uma boa forma de dividir o programa em componentes,
ou mdulos, mas resta ainda a tarefa de saber quais os mdulos que devem ser criados para um
determinado sistema. A resposta a esta pergunta no est na especificao de requisitos, o analista tem
de construir alternativas e escolher a melhor.

3.3 Caractersticas de um bom Desenho


O desenho do sistema uma tarefa de alta importncia, uma vez que influencia o decorrer das restantes
www.moodle.univ-ab.pt//print.php?id 16/85
26-01-2010 name
fases do projecto. desejvel que:

Os diversos componentes de software sejam independentes;


Cada componente de software seja coeso.

Apenas se existir independncia de componentes estes podem ser desenvolvidos e mantidos em


separado. Desta forma o projecto poder ser to grande e complexo, que o programador responsvel
por implementar um componente poder abstrair-se de tudo o resto e desenvolver o componente sem ter
que considerar o resto do projecto. Num projecto grande permite tambm que os diversos componentes
sejam implementados em paralelo por vrios programadores. Caso no se consiga a independncia dos
componentes, no s se limita o tamanho e complexidade do projecto que pode ser implementado por
um programador que um ser humano e portanto tem limitaes, como se impede que os diversos
componentes sejam implementados em paralelo.

A coeso de um componente um factor essencial para a razo de ser do componente. Caso um


componente no seja coeso, ento as suas partes esto juntas por puro acaso. No h vantagem em
serem implementadas em conjunto, pelo que devem ser divididas em vrios componentes mais pequenos
de forma a serem implementadas em separado.

3.4 Independncia de Componentes


A independncia de componentes o grau de independncia que os diversos componentes tm entre si.
A independncia de componentes uma caracterstica desejvel num bom desenho. Podem ocorrer
diversos nveis de dependncias:

Contedo - quando as variveis de um componente so modificadas por outro componente;


Comum - quando os dados esto num local comum e so alterados por diversos componentes;
Controlo - quando um componente A controlado atravs de argumentos invocados de outro
componente B, no podendo o componente A funcionar de forma independente de B;
Selo - quando uma estrutura de dados passada entre componentes;
Dados - quando apenas dados so passados entre componentes;
No dependentes - quando no h passagem de dados entre componentes.

Na programao orientada por objectos, se todas as variveis forem privadas evita-se no mnimo a
dependncia de Selo entre classes, o que aceitvel. Caso no se passe estruturas de dados entre
objectos, as dependncias entre componentes so quanto muito dependncias de Dados, o que
desejvel que assim seja.

Um exemplo de um erro em programao orientada por objectos, que tem consequncias nos custos
de desenvolvimento e manuteno: A dependncia de contedo de uma classe A com outras classes B1,
B2, ... Bn, por exemplo, obriga a sempre que se acrescente algo na classe A, se tenha de analisar e
testar as classes B1,...,Bn, ou quando se descobre um valor errado numa varivel da classe A, se tenha
de ver o cdigo para tentar perceber, no s da classe A como tambm das classes B1,...,Bn. Impede
tambm o teste de unidades de forma independente da classe A relativamente s classes B1,...,Bn.

3.5 Coeso de um Componente

Um componente diz-se coeso se constitudo por partes que se relacionem entre si. A coeso de
componentes uma caracterstica desejvel num bom desenho. Pode ocorrer a diversos nveis:

Funcional - quando as partes se destinam todas a implementar a mesma funo, e apenas essa
funo;
www.moodle.univ-ab.pt//print.php?id 17/85
26-01-2010 name
Sequencial - quando o resultado de uma parte entrada para a outra parte, e as partes tm de ser
executadas em sequncia;
Comunicacional - quando as partes tm de produzir ou alterar o mesmo conjunto de dados, ou um
recurso externo;
Procedimental - quando as partes esto juntas apenas por deverem ser chamadas em conjunto por
uma determinada ordem;
Temporal - quando as partes esto relacionadas pela altura em que so chamadas, por exemplo,
todos os procedimentos de inicializao juntos no mesmo componente;
Lgica - as partes esto relacionadas apenas ao nvel lgico, por exemplo, todos os
procedimentos de entrada de dados juntos no mesmo componente;
Coincidental - as partes do componente no tm qualquer relao entre si.

ideal que as coeses dos componentes sejam funcionais. Assim, ao dar a um programador uma
funcionalidade para implementar ou para testar, ir desenvolver/analisar apenas um componente. Quando
h um erro detectado, normalmente sobre uma determinada funcionalidade que no est a ser
verificada, e dever ser fcil identificar o componente que no est a funcionar bem, uma vez que a
coeso funcional.

No outro extremo, da coeso dos componentes ser coincidental, qualquer das tarefas descritas no
pargrafo anterior vo obrigar anlise de todos os componentes. Mesmo que o programador tenha
tudo em mente, caso tenha acabado de escrever o cdigo (assumindo que apenas ele escreveu cdigo),
mesmo assim h penalidade de ter de alterar/ver vrios componentes, que normalmente esto em vrios
ficheiros.

A coeso sequencial e comunicacional so ainda aceitveis, ficando a coeso procedimental no limite. Os


restantes tipos de coeso so de evitar.

3.6 Melhorar o Desenho

O Desenho deve ser devidamente revisto e optimizado antes de se comear a implement-lo. Existem as
seguintes alternativas:

Reduo da Complexidade - tentar reduzir de alguma forma a complexidade das especificaes


ou da estrutura de dados, o que pode envolver conhecimentos matemticos ou da rea do
problema;
Prottipo de Desenho - actualmente os ambientes de desenvolvimento permitem ter o sistema
pronto a correr, pelo que no necessrio fazer prottipos para deitar fora;
Desenho por contracto - obsoleto com a programao orientada por objectos;
Anlise de rvore-de-falhas - tcnica para detectar incoerncias.

O desenho por contracto perde o sentido na programao orientada por objectos, em que cada classe
segue essa filosofia. A anlise de rvore-de-falhas no concretamente uma tcnica para melhorar um
desenho, excepto se se chamar a deteco de uma incoerncia e respectiva remoo de incoerncia um
melhoramento do desenho.

A nica real maneira de optimizar um desenho reduzindo a complexidade do Desenho, atravs da


escolha de um Desenho alternativo. Conhecimentos matemticos ou conhecimentos da rea do problema
a nica alternativa. No entanto, ateno! Mais vale um Desenho simples que se sabe estar em
condies e de acordo com os Requisitos que um Desenho optimizado mas incerto.

3.7 Verificao e Validao do Desenho


www.moodle.univ-ab.pt//print.php?id 18/85
26-01-2010 name
O ltimo passo na fase de Desenho verificar e validar o Desenho. Para tal h algumas tcnicas que se
podem utilizar: validao matemtica; clculo de indicadores de qualidade; comparao de desenhos;
revises de desenho.

A validao matemtica permite em partes mais algortmicas provar que o algoritmo satisfaz os
requisitos. Muitas vezes esta tcnica consome demasiado tempo, dependendo da complexidade do que
se pretende provar.

O clculo de indicadores de qualidade do desenho permite efectuar a comparao entre desenhos


alternativos. Estes indicadores esto desenvolvidos para a programao orientada por objectos.
Permitem tambm a comparao de desenhos, que basicamente a partir da mesma especificao se
constri vrios desenhos, escolhendo-se o desenho com base numa anlise multi-critrio.

Uma reviso de desenho uma reunio com o intuito de verificar e validar o desenho. A reviso
preliminar do desenho destina-se a verificar se o desenho conceptual corresponde ao que o cliente
pretende e est de acordo com os requisitos. A reviso crtica do desenho e a reviso do programa
de desenho, destinam-se a verificar o desenho tcnico. As reunies devem ser feitas com algum
formalismo, devendo existir um secretrio responsvel por redigir uma Acta com os principais pontos
apontados escritos de forma clara e concisa. O cliente deve estar presente nas revises preliminares do
desenho. Deve-se convidar colegas no envolvidos no projecto, mas deve-se manter o nmero de
participantes reduzido de forma a facilitar o dilogo.

3.8 Medidas em Programao Orientada por Objectos


Em Programao Orientada por Objectos (POO) existem medidas de esforo de implementao e
manuteno de software, mais precisas das que esto disponveis para programao estruturada. Estas
medidas so no entanto vlidas para Engenharia de Software no geral, uma vez que se podem adaptar
tambm para a programao estruturada, basta que para tal se pense num mdulo ou componente como
sendo uma classe. Estas medidas podem estar disponveis apenas em algumas fases do projecto.

Mtricas propostas por Lorenz & Kidd:

Nmero de Operaes ("number of scenario scripts" / NSS);


Nmero de classes principais;
Nmero de classes auxiliares;
Rcio de classes auxiliares por classes principais;
Nmero de subsistemas;
Tamanho da classe (nmero de mtodos e atributos prprios e herdados);
Nmero de mtodos redefinidos pela subclasse ("number of operations overridden by a subclass" /
NOO);
Nmero de mtodos adicionados pela subclasse;
ndice de especializao ("specialization index" / SI), SI=(NOOxnvel)/(nmero de mtodos).

Nota: As primeiras cinco mtricas podem ser utilizadas em fases iniciais do projecto, para decidir entre
desenhos alternativos, ou ter uma primeira ideia do esforo de implementao. As ltimas 4 mtricas so
mais centradas na classe, muito embora sejam bastante superficiais, uma vez que consideram os mtodos
todos com igual contribuio para o tamanho da classe, assim como os atributos.

Exemplo de SI: Uma classe definida a partir de uma s super-classe, com 10 mtodos redefinidos de
um total de 33 mtodos da super-classe, tendo a classe mais 3 mtodos novos. O nvel da classe 1
uma vez que s h uma super-classe. Aplicando a frmula tem-se: SI=10*1/36=0,28.

www.moodle.univ-ab.pt//print.php?id 19/85
26-01-2010 name
Mtricas propostas por Chidamber & Kemerer:

Mtodos pesados por classe ("weighted methods per class"/ WMC) - deixa a complexidade de
cada mtodo em aberto;
Nvel da rvore de herana ("depth of inheritance tree" / DIT);
Nmero de subclasses ("number of children" / NOC) - subclasses imediactas;
Dependncias entre objectos ("coupling between objects" / CBO) - nmero de classes que
interagem com a classe;
Resposta de uma classe ("response for a class" / RFC) - nmero de mtodos que podem ser
executados em resposta a uma mensagem;
Falta de coeso dos mtodos ("lack of cohesion of methods" / LCOM) - max{0;|P|-|Q|}; P -
conjunto de pares de mtodos cujos atributos que utilizam so disjuntos; Q - conjunto de pares de
mtodos que utilizam um ou mais atributos em comum.

Notas: estas mtricas so mais detalhadas e tambm relevantes para a estimativa do esforo de
implementao/manuteno de cdigo, mas mantendo a simplicidade. A mtrica mais complicada de
calcular a falta de coeso. Nesta mtrica consideram-se todos os pares de mtodos, e v-se para cada
par se utilizam atributos da classe em comum ou no. Caso a maior parte dos pares utilize atributos em
comum, a falta de coeso nula, caso contrrio a falta de coeso o nmero de pares a mais que no
tm atributos em comum.

Exemplo de LCOM: Uma classe tem um atributo, que utilizado no mtodo m1 e m2, tendo tambm
os mtodos m3 e m4 que no utilizam o atributo da classe. O nico par de mtodos com atributos em
comum o (m1,m2), e os restantes 5 pares no tm nada em comum. A classe tem portanto valor 5-1=4
de falta de coeso.

Mtricas propostas por Li & Henry:

Dependncia de mensagens ("message-passing coupling") - nmero de chamadas definidas na


classe;
Dependncia de dados ("data abstraction coupling") - nmero de dados abstractos utilizados na
classe.

Notas: estas duas mtricas complementam a dependncia de objectos.

Mais informao: http://pt.wikipedia.org/wiki/M%C3%A9tricas_de_software

Exemplo: Poker, Desenho Conceptual

altura de se dar uma soluo ao problema do cliente, mas ainda na linguagem do cliente, de forma a
que este valide a soluo proposta. Este exemplo, sendo um simulador, temos de indicar de alguma
forma o essencial do algoritmo.

Parmetros:

semente aleatria;
nmero de jogadores;
nmero de cartas fechadas;
nmero de cartas abertas;
nmero de jogos.

Algoritmo:

www.moodle.univ-ab.pt//print.php?id 20/85
26-01-2010 name
1. Baralhar o baralho de cartas;
2. Dar cartas a cada jogador;
3. Calcular a melhor mo de cada jogador (ordenar as cartas do jogador com as cartas da melhor
mo em primeiro lugar);
4. Mostrar resultado.

O ponto 3 do algoritmo aqui o desafio, e tambm o ponto que poderemos necessitar de validao da
parte do cliente, pelo que deve ser detalhado. Evidentemente que, se o cliente no conseguir
compreender, este ponto pode passar para o desenho tcnico.

Calcular melhor mo:

1. Verificar pares, trio, poker e fullen;


2. Verificar sequncia*;
3. Verificar cor**;
4. Verificar sequncia e cor (incluindo a real);
5. Ordenar as cartas, primeiro as cartas do tipo da mo, e as restantes por ordem de nmero;
6. Retornar o tipo de mo: 0 - nada; 1 - par; 2 - 2Pares; 3 - trio; 4 - sequncia; 5 - cor; 6 - fullen; 7
- poker; 8 - sequncia e cor; 9 - sequncia e cor real.

* - executar apenas se o resultado for nesse passo inferior a 4


** - executar apenas se o resultado for nesse ponto inferior a 5

Verificar pares, trio, poker e fullen:

1. Ordenar as cartas por nmeros (pares, trios, quadras ficam todas seguidas);
2. Processar todas as cartas, e para cada carta:
1. Se existirem 3 cartas seguintes com o mesmo nmero da carta actual, ento o resultado
passa a poker=7;
2. Se existirem 2 cartas seguintes com o mesmo nmero da carta actual, ento o resultado
passa a trio=3. No entanto, se j tiver sido detectado um par, dois pares ou outro trio,
ento o resultado passa a fullen=6;
3. se existir 1 carta seguinte igual, ento o resultado passa a par=1. Se j foi detectado um
par, ou dois pares, ento o resultado dois pares=2. Caso tenha sido detectado um trio, o
resultado passa a fullen=6.

Verificar sequncia:

1. Processando as cartas por ordem novamente:


1. Caso a sequncia esteja vazia, guardar o nmero da carta actual;
2. Se o ltimo nmero da sequncia igual carta actual, no fazer nada, passar para a
prxima carta;
3. Se o ltimo nmero da sequncia anterior ao nmero actual, adicionar o nmero actual
sequncia. Se a sequncia ficar com 5 cartas, ento o resultado sequncia=4, e pra.
4. Se o ltimo nmero da sequncia difere em mais de uma unidade ao nmero da carta actual,
esfaziar a sequncia e inicializar com o nmero actual.

Verificar Cor:

1. Processar todos os naipes:


1. Processar todas as cartas:
1. Se a carta actual o naipe actual, incrementar contador;

www.moodle.univ-ab.pt//print.php?id 21/85
26-01-2010 name
2. se o contador atingiu o valor 5, o resultado cor=5, e pra.

Verificar sequncia e cor:

1. Processar todos os naipes:


1. Processar todas as cartas:
1. Se a carta actual o naipe actual:
1. Se j esto cartas na sequncia+cor e o nmero da ltima difere em mais de
uma unidade com o nmero da carta actual, esvaziar as cartas em
sequncia+cor;
2. Colocar a carta actual em sequncia+cor;
2. Se o nmero de catas em sequncia+cor 5:
1. Se o A est presente, o resultado SCR=9;
2. Caso contrrio o resultado SC=8
3. Parar.

Se o cliente no compreender a descrio do algoritmo, no h nada a fazer, mas se tal no for o caso, a
vantagem do cliente validar a soluo apresentada muito importante porque: por um lado retira ao
analista parte da responsabilidade de garantir que a soluo proposta resolve o problema do cliente, e
por outro lado permite ao cliente reflectir se o problema que especificou realmente o problema do qual
necessita de uma soluo. Caso o desenho conceptual no seja devidamente compreendido pelo cliente,
este s ir reflectir quando tiver a primeira verso da aplicao, altura em que compreende realmente
qual tinha sido a soluo proposta.

Exemplo: Poker, Desenho Tcnico

Nesta fase necessrio dar solues tcnicas, no necessrio ter a preocupao de fazer um
documento que o cliente compreenda, mas sim que o programador compreenda, e possa com base nele
construir uma aplicao.

Dado que o cliente no especificou nenhuma interface com o utilizador, e para facilitar os testes, faremos
uma aplicao de linha de comando e que funciona com o EngineTester. Esta opo no nos restringe
futuras utilizaes do cdigo em outros contextos, apenas nos facilitar a interface e tambm os testes.
Para tal necessrio reutilizar cdigo do EngineTester com as classes: TEngine; TVector; TRand, sendo
fornecido tambm o cdigo da funo main. Tem que se redefinir uma subclasse de TEngine para o
problema concreto, e as classes especficas.

Atravs da documentao existente podem-se identificar vrios candidatos a classes: Carta; Baralho;
Mo; TipoMo; Jogador; Jogo. A experincia e o bom senso so essenciais, podendo nesta altura tanto
simplificar um problema complexo, como complicar um problema simples. As indicaes neste captulo
sobre um bom ou mau desenho devem ser lidas e questionadas principalmente por quem no tenha ainda
muita experincia. Neste caso concreto, quais dos candidatos a classe descritos acima valem a pena
passar para classe? Nenhum. No entanto, de toda a convenincia a criao de uma classe. Vamos
comear por analisar os candidatos a classe:

Carta - Tem como atributos o naipe e nmero. Tem algum mtodo? No. Os atributos mudam ao
longo do tempo? No. Ainda por cima cabe num s byte, pelo que no faz sentido uma classe.
Baralho - Esta classe poderia guardar para cada carta o local onde est, e em que posio.
Poderia ter um mtodo para baralhar, outro para ordenar as cartas que esto num local, e um
mtodo para calculo da melhor mo para as cartas de um determinado local. O nico mtodo a
utilizar todas as cartas seria o mtodo Baralhar, de resto os restantes s utilizam parte dos dados
da classe, pelo que faz mais sentido uma classe que tenha um conjunto de cartas em vez de ter
www.moodle.univ-ab.pt//print.php?id 22/85
26-01-2010 name
todas as cartas separadas por local.
Mo - Esta a classe mais parecida com um conjunto de cartas, dado que uma mo um
conjunto de cartas, mas o nome deixa de fora a possibilidade de ter todo o baralho, pelo que um
nome Cartas mais geral e indicativo do conceito que representa, um conjunto de cartas.
TipoMo - Poderia haver um conjunto de classes em que cada uma tinha um mtodo para
detectar se uma mo era desse tipo ou no, mas como se viu no desenho conceptual, h vantagem
em verificar todos os tipos de mo de uma s vez, numa s funo por uma ordem especfica. Esta
classe a existir teria apenas mtodos, o que no um bom indicador para uma classe.
Jogador - Os atributos seriam as cartas que um jogador possui, ou seja, um objecto com um
conjunto de cartas. A classe contem um s atributo, no h mtodos que no sejam aplicados
directamente ao nico atributo que possui, pelo que a criao desta classe, para j no trs
vantagens.
Jogo - Dado que se pretende simular 1 jogo, no h vantagem aparente. Quando se pretender
simular vrios jogos e manter os jogos em memria, ento nessa altura far sentido a criao desta
classe.

Aconselha-se portanto a criao da classe especfica TCartas e redefinio da classe TEngine, a classe
TCartasEngine.

Este diagrama de classes tem para as classes reutilizadas os atributos e mtodos que so relevantes para
a nossa implementao, e para as classes implementadas os atributos e mtodos que se prev serem
necessrios.

O TVector uma classe que para gerir a alocao/dealocao de vectores de objectos de uma classe
arbitria Item. Tem os mtodos convenientes a uma abstraco tanto a uma sequncia de objectos,
como a um conjunto de objectos. So apresentados no diagrama os mais teis para o nosso problema. A
classe TRand tem um gerador de nmeros aleatrios implementado, utilizado pelo TVector para o
mtodo RandomOrder, o que permite manter o output constante no caso do cdigo ser compilado num
outro compilador, o que no aconteceria se se utilizar o gerador de nmeros aleatrios de uma biblioteca
disponvel num compilador especfico.
www.moodle.univ-ab.pt//print.php?id 23/85
26-01-2010 name

O TEngine uma classe abstracta, que tem 5 vectores com informao sobre os parmetros. Para cada
parmetro tem de existir um valor em cada um dos vectores (mais correcto seria ter feito uma classe
para parmetro, e um vector de parmetros). Cada parmetro tem um valor, um nome, uma descrio,
um valor mximo e um valor mnimo. As unidades so sempre em inteiros. Os parmetros devem ser
inicializados no mtodo Reset. O mtodo Run deve ter o algoritmo, que deve aceder ao vector value
para obter o valor dos parmetros, que podem no ser os inicializados no mtodo Reset no caso do
utilizador ter alterado o valor de omisso. A classe TCartasEngine deve portanto redefinir esses dois
mtodos.

O mtodo TCartas tem um TVector com o conjunto de cartas, sendo cada carta um char. Para aceder
ao nmero e naipe de uma carta, os mtodos estticos Numero e Naipe esto definidos, bem como para
construir uma carta com o nmero e naipe, pode-se utilizar o mtodo esttico Carta. O mtodo Baralho
inicializa este conjunto de cartas com todas as cartas do baralho, enquanto que o mtodo Poker calcula o
valor da melhor mo disponvel (o algoritmo principal), existindo ainda um mtodo Dar, que retira n
cartas deste conjunto de cartas, e coloca-as no conjunto de cartas mao. No necessrio um mtodo
para baralhar, j que TVector j tem o mtodo RandomOrder.

Vamos ficar por aqui, os mtodos Run e Poker esto no desenho conceptual, sendo provavelmente mais
penosa a construo de um diagrama de actividades do que propriamente o cdigo. Os mtodos
Baralho e Dar tm uma implementao simples, e embora a utilizao da classe TVector facilite, mesmo
sem esta classe apenas se ter cuidado na alocao de memria e implementar um algoritmo de
ordenao e outro para baralhar. portanto altura de comear a escrever o cdigo!

"Software Engineering, theory and practice", second edition, Prentice Hall, Shari Pfleeger, pg. 196-201,
220-225, 231-248, 294-300.

www.moodle.univ-ab.pt//print.php?id 24/85
26-01-2010 name

4 - Cdigo
Esta a parte do processo em que se d realmente instrues ao computador para que sejam
executadas de forma automtica: o cdigo. No se ensina aqui a escrever cdigo, a programar, essa
matria j deve ser do conhecimento do estudante. Neste captulo estamos interessados em programar
bem, no em termos de conseguir implementar um algoritmo complexo e eficiente, mas em termos de
facilidade de escrita e de leitura.

Cdigo complexo e brilhante, com documentao interna de forma a ser lida por pessoas inteligentes,
com capacidade de ler e apreciar a obra de arte, ser lido por um colega apenas aps algum bug ter sido
reportado, e a sua apreciao ser mais do tipo: "que grande baralhada que para aqui anda".

Como se pode tornar mais fcil a escrita? Atravs de um ambiente de desenvolvimento com auxiliares de
memria e de escrita, levando a que o cdigo fique partida com menos erros e simultaneamente leve
menos tempo a ser escrito, contribuindo ambos os pontos para a reduo do custo do software, e para o
aumento do prazer de programar.

A reduo do tempo de escrita do cdigo consegue-se apenas se o cdigo for escrito com calma. Caso
o cdigo seja escrito pressa, independentemente do ambiente de desenvolvimento, o nmero de erros
sobe e a quantidade de trabalho feita que no final no serve para nada aumenta, levando a um aumento
no tempo de escrita de cdigo.

Como se pode tornar mais fcil a leitura? Aqui o ambiente de desenvolvimento tem tambm influncia,
mas com menor relevo. A boa documentao interna, a utilizao de uma norma de escrita de cdigo e a
reutilizao de cdigo a base para se conseguir escrever cdigo de fcil leitura e portanto mais
facilmente testvel e com menores custos de manuteno.

Caso algo corra mal nesta fase, no se pode concluir que a culpa do programador. Existe tambm o
prprio problema que deveria estar resolvido na fase de desenho. Caso tenha que ser implementado um
algoritmo complexo, no completamente definido na fase de desenho, o programador pode no ter bases
matemticas para o compreender e implementar. Ou o mdulo a implementar pode ser demasiado
grande e o desenho actual no permitir abstraces. Nesse caso o programador poder no ter
capacidade para compreender e implementar o mdulo. portanto necessrio que a fase de desenho
seja bem realizada para que esta fase tambm o seja. O bom senso manda tambm que se atribua os
mdulos mais complexos aos programadores mais experientes.

4.1 Ambiente de Desenvolvimento


Como pode um ambiente de desenvolvimento facilitar a escrita do cdigo? Para responder a esta
pergunta vamos descrever brevemente a escrita do cdigo de um programador com um editor de texto,
um compilador e debuguer de linha de comando, que so as ferramentas mnimas para escrever cdigo,
aps o qual iremos ver os diferentes aspectos em que podem ser melhorados com um Ambiente de
Desenvolvimento.

4.1.1 Editor de texto, compilador e debuguer


Com base no desenho tcnico, a primeira tarefa criar os ficheiros necessrios, o que depende da
linguagem e de opes do programador. Dois ficheiros por cada classe necessria, um com a declarao
e outro com a implementao, a escolha normal. Num caso extremo pode-se criar um s ficheiro com
todo o programa, complicando a navegao pelo cdigo.

www.moodle.univ-ab.pt//print.php?id 25/85
26-01-2010 name
Num segundo passo tem que se escrever as declaraes das classes, e escrever as implementaes dos
diferentes mtodos vazios, bem como tudo o que necessrio para o programa se poder compilar, e
finalmente compilar o programa. Aps alguns acertos entre nomes das classes e mtodos que esto
ligeiramente diferentes na declarao e implementao, o programa compila.

No terceiro passo comea-se a escrever cdigo propriamente dito, a implementao de cada mtodo de
uma classe. Nessa altura necessrio conhecer para que servem todos os atributos da classe e restantes
mtodos, bem como ter o conhecimento das classes e bibliotecas que so utilizadas. Aps cada mtodo
escrito, h que compilar para ver os erros de sintaxe. Nomes de atributos/mtodos mal escritos, blocos
de cdigo mal fechados, argumentos do tipo errado, so exemplos de erros de sintaxe encontrados e
corrigidos. O compilador d uma lista de defeitos, com a linha em que ocorrem. Infelizmente o defeito no
cdigo pode ser originado por um erro em outra zona do cdigo, provavelmente anterior, e o mesmo
erro pode originar muitos defeitos. Como se v a lista de defeitos, convm aps a localizao do erro
voltar a compilar para obter a lista actualizada de defeitos. Este processo deve ser repetido aps cada
mtodo para limitar a zona que se tem que procurar pelos erros.

Num quarto passo, aps uma classe estar completamente escrita, convm preparar um pequeno bloco
de teste para ver se a classe est a fazer o que era suposto. O programa compila e corre o bloco de
teste. Este passo deve ser feito sem ansiedade, j que tem-se a certeza que haver problemas. Aps
confirmada a dura realidade tem que se obter mais informao sobre o que no est correcto,
normalmente espalhando informao de debug do que est a ser feito a cada momento para o ecran.
Pode-se tambm utilizar um debuguer de linha de comando, o qual permite correr o programa e parar
numa determinada linha de cdigo, podendo nessa altura consultar o estado do programa,
nomeadamente consultar o valor das variveis, saber quais os mtodos chamados e com que
argumentos, etc. Ao detectar um problema so introduzidas alteraes ao cdigo para que este funcione
melhor e repete-se o processo. Por vezes as alteraes no resolvem e criam elas mais problemas, mas
eventualmente todos os problemas ficam resolvidos e o primeiro teste classe implementada passado
positivamente.

As outras classes vo sendo feitas, algumas delas passando por cima do ponto quatro, isto , no so
testadas em separado de forma a no perder tempo a fazer o cdigo de teste. Uma altura chegar em
que tudo est implementado. Nessa altura o cdigo novamente testado atravs de um processo
idntico ao ponto quatro mas com cdigo suspeito todo o cdigo produzido e no apenas uma
classe. Nesta altura normal dizer que o cdigo j est feito, s falta testar, sendo de prever que logo
que o cdigo corra uma vez correctamente, seja dado como cdigo a funcionar, no havendo lugar a
mais demora.

claro que tudo isto possvel acabar aqui caso o desenho esteja em condies. Se o nosso
programador teve a sorte de ter um colega experiente que fez o desenho, ento tudo bate certo. Caso o
desenho tenha sido feito por algum sem experincia, descobre agora que o desenho no dava para
resolver o problema em questo, era at incoerente, pelo que no consegue completar o programa para
fazer o teste final.

4.1.2 Melhoramentos
Pode-se facilitar a escrita de cdigo primeiro no editor de cdigo. O editor deve conhecer a sintaxe da
linguagem de programao, de forma a colorir as palavras pertencentes linguagem, bem como o incio e
fim de blocos. Deve tambm ter conhecimento dos restantes ficheiros pertencentes ao projecto, de forma
a poder identificar nomes de atributos e mtodos vlidos, identificando assim os mal escritos. Desta
forma, erros de sintaxe so detectados logo em tempo de edio e corrigidos. Este conhecimento
aproveitado tambm para facilitar a escrita. Ao escrever as primeiras letras de um atributo ou mtodo, o
www.moodle.univ-ab.pt//print.php?id 26/85
26-01-2010 name
editor fornece logo as vrias possibilidades que existem para completar com um nome vlido.

Ao criar uma nova classe, o ambiente de desenvolvimento cria logo os ficheiros de declarao e
implementao, e o cdigo essencial, dependente naturalmente da linguagem de programao. Pode-se
adicionar um mtodo ou atributo atravs do ambiente de desenvolvimento, sendo colocada logo uma
declarao e implementao nos ficheiros respectivos. Ao chamar-se um determinado mtodo tem que
se conhecer o que este faz e quais os seus argumentos. Durante a escrita, ao comear a escrever os
argumentos de um mtodo, o editor apresenta de imediacto ao programador no s os argumentos na
declarao do mtodo, como tambm o comentrio que est junto da declarao com a descrio do
que o mtodo faz.

A navegao pode ser tambm melhorada. Sem ambiente de desenvolvimento, o programador quando
quiser ir para a implementao de um mtodo, tem que saber em que ficheiro est, abrir o ficheiro no
editor, e navegar no ficheiro at ao mtodo. O ambiente de desenvolvimento pode listar todas as classes
e mtodos do projecto, independentemente dos ficheiros em que esto, permitindo ao utilizador ir
directamente para a declarao ou implementao do mtodo. Naturalmente que se o programador
necessitar, pode efectuar procuras ou substituio de texto num ou em todos os ficheiros do projecto.

A integrao do editor, compilador e debuguer, permite por um lado que da lista dos erros de
compilao se v directamente para a linha do cdigo onde o erro foi detectado, e por outro lado que se
possa colocar pontos de paragem no cdigo e mandar correr, e ao parar o programa obtem-se logo
janelas com o estado do programa. Pode-se nessa altura efectuar algumas alteraes ao cdigo e
compilar continuando a correr o programa com a actualizao, no sendo necessrio em muitas
situaes reiniciar a corrida.

As vantagens a nvel do editor, navegao pelo projecto e do debuger, so determinantes na


produtividade do programador. No Tuturial do Visual C++ 2008 Express Edition so descritas
diversas funcionalidades do ambiente de desenvolvimento. essencial conhecer e experimentar para
decidir entre utilizar ou no. Ficar na ignorncia poder significar uma perda de produtividade e conforto
na escrita de cdigo.

Encontram-se com certa facilidade programadores experientes utilizando o ambiente de desenvolvimento


editor+compilador+debuguer desintegrado, sendo a integrao o sistema operativo. Estes
programadores no vm vantagem nos novos ambientes de desenvolvimento integrados. Difcil
encontrar programadores que tenham utilizado ambientes de desenvolvimento integrados num projecto
concreto e tenham voltado ao editor+compilador+debuguer.

As diferentes ajudas nunca devem ser vistas de forma a que o programador no necessite de saber isto
ou aquilo. O programador responsvel por todo o cdigo, excepto o cdigo das bibliotecas que
utilizar, que tem de o ler e perceber, mesmo que parte deste tenha sido escrito automaticamente pelo
ambiente de desenvolvimento.

4.2 Reutilizao de Cdigo


A reutilizao de cdigo pode dar-se a dois nveis: produo de cdigo reutilizvel; consumo de cdigo
reutilizvel.

Consumidores de cdigo reutilizvel devem ter em ateno aos seguintes pontos:

O componente executa a funo e devolve a informao necessria?


Se for necessria uma pequena modificao, essa modificao menor que construir o
componente de raiz?
www.moodle.univ-ab.pt//print.php?id 27/85
26-01-2010 componente de raiz? name
A documentao permite compreender o componente sem ter de se ver o cdigo linha a linha?
Existe o historial de falhas corrigidas?

Esta ltima pergunta poder pensar-se que deva ser ao contrrio. Como natural que o cdigo tenha
falhas, a existncia do historial de falhas corrigidas apenas vem dar informao que o cdigo foi bastante
testado e pode ser utilizado com segurana. Se por outro lado nada se saber sobre falhas, quer dizer que
no se encontrou falhas porque se testou pouco.

Os produtores de cdigo reutilizvel devem ter em ateno aos seguintes pontos:

Fazer o componente genrico, utilizando sempre que possvel parmetros em vez de constantes;
Separar partes que eventualmente possam ter de ser alteradas das que provavelmente nunca sero
alteradas;
Manter historial de falhas corrigidas;
Respeitar a norma de escrita de cdigo (formatao; comentrios; nomes; estilo).

Estes pontos podem ser respeitados o mximo possvel, mesmo ao escrever cdigo que no para ser
reutilizado. Isto porque na verdade no se sabe se no ir aparecer no prprio programa uma situao
em que o cdigo que se est a escrever no possa ser reutilizado, e depois porque o mdulo a construir
pode vir a ser repensado e feito reutilizvel para outros projectos. Estes pontos facilitam tambm a fase
de testes.

4.3 Norma de Escrita de Cdigo


Esta seco destina-se a normalizar a escrita de cdigo, sendo apenas uma possibilidade entre outras. O
intuito da normalizao tornar a leitura de cdigo mais simples, tanto de outras pessoas como do
prprio autor. Desta forma reduz-se custos de teste e manuteno.

Esta seco est orientada para terminologia da programao orientada por objectos, mas pode ser
utilizado tambm na programao estruturada e programao funcional. A correspondncia de classe
para programao estruturada poder ser mdulo ou ficheiro de cdigo, enquanto que a
correspondncia de mtodo ser funo ou procedimento.

O ambiente de desenvolvimento em programao orientada por objectos tratar da criao dos ficheiros,
devendo os nomes serem iguais aos nomes das classes. Caso assim no seja, dever ser criado um
ficheiro por cada classe, com o mesmo nome da classe, ou dois no caso de existir ficheiro de declarao
e implementao. Em programao no orientada por objectos, o projecto deve ser dividido em
mdulos, ficando cada mdulo num ficheiro. Os mdulos devem conter funes que estejam relacionadas
entre si, e no devem ser muito grandes.

A lngua utilizada deve ser sempre a mesma ao longo de todo o cdigo, tanto no nome das variveis e
funes como nos comentrios.

1. Formatao

1.1 Indentao: Cada linha de cdigo deve comear por 4 espaos por cada bloco de cdigo em que
estiver inserido. aceitvel em vez de 4 espaos utilizar outro valor, desde que seja sempre o mesmo
para todo o ficheiro.

Exemplos C++:

www.moodle.univ-ab.pt//print.php?id 28/85
26-01-2010 name
As duas primeiras linhas e a ltima, no esto dentro
de bloco nenhum, enquanto que a 3, 4 e 6 linha
esto dentro do bloco de cdigo do mtodo, sendo
antecedidas de 4 espaos. A 5 linha est ainda
dentro do bloco do ciclo for, pelo que sobe 8
espaos.
Este cdigo est aparentemente bem indentado, no
entanto utiliza 2 espaos para a 3, 4 e 6 linha,
enquanto que para a 5 linha utiliza 6 espaos. Se a
indentao a 2 espaos, a 5 linha teria de ter 4
espaos e no 6.

1.2 Tamanho das linhas: As linhas tanto cdigo como de comentrios no devem exceder os 80
caracteres. Caso tal no seja possvel, a linha de cdigo deve ocupar mais que uma linha. Conta para
efeitos de indentao a segunda linha e seguintes, como se estivessem dentro de mais um bloco de
cdigo. Uma linha de comentrio que continue na linha seguinte mantm a indentao.

1.3 Argumentos: As listas de argumentos, tanto na definio como na utilizao, no so considerados


blocos de cdigo. Assim devem ser escritos na mesma linha, se possvel, caso contrrio aplica-se o
ponto 1.2.

1.4 Incio e fim de bloco: A marca de incio e de fim de bloco de cdigo deve utilizar uma linha para o
incio e outra para o fim do bloco. As linguagens funcionais podem ignorar esta regra, uma vez que em
geral o primeiro elemento do bloco um identificador e convm que fique na mesma linha que a abertura
de bloco.

Exemplo de C++ e Lisp:


O incio de bloco deste cdigo est na mesma linha
que o nome do mtodo, o que est incorrecto.
Deve-se utilizar uma linha separada.
Em Lisp o incio de bloco igual ao incio de
argumentos e colocado antes do identificador,
pelo que no faz sentido uma linha nova. Ao fechar
o bloco usual no utilizar novas linhas.

A questo da indentao muitas das vezes vista como uma opo pessoal. Cada um acha que indenta
bem o cdigo, o que leva a que cada cdigo que se leia fique na sua indentao prpria, perdendo-se
parte da vantagem para quem l. J o cdigo no indentado por completo torna a leitura tortuosa, dado
que fora o leitor a prestar grande ateno ao incio e fim de blocos, ateno essa que faz parte das
obrigaes de quem escreve e assim passa tambm para quem l o cdigo, caso este no esteja
indentado.

2. Comentrios

2.1 Localizao: Os comentrios devem anteceder o cdigo que comentam. Pode-se colocar pequenos
comentrios ao bloco na prpria linha de incio ou fim de bloco de cdigo.

2.2 Comentrio de classe: No incio de cada classe deve existir um comentrio de classe. Neste
comentrio deve conter informao sumria sobre a classe. D-se liberdade de incluir mais ou menos
campos conforme apropriado, no entanto o comentrio de classe deve ter obrigatoriamente os campos
(ingls/portugus):
www.moodle.univ-ab.pt//print.php?id 29/85
26-01-2010 name

Author/Autor - uma ou mais pessoas que contriburam para a classe


Last change/ltima modificao - data da ltima modificao
Description/Descrio - descrio da estrutura de dados e breve descrio dos algoritmos
envolvidos, esclarecendo o que os algoritmos fazem e no como fazem

2.3 Comentrio de mtodo: Cada mtodo deve ter um comentrio inicial, idntico ao comentrio de
classe, acrescentando:

Descrio do algoritmo, no s o que faz mas tambm como o faz;


A complexidade temporal do algoritmo, sempre que possvel. No incio dos blocos de cdigo
pode-se colocar tambm a complexidade temporal do bloco de cdigo;
Pr e ps-condies de utilizao do mtodo, por exemplo, os elementos de uma lista estarem
ordenados;
Incluir eventuais restries de utilizao, por exemplo, o valor mximo para cada argumento do
mtodo para o qual o mtodo foi testado e funciona bem. Aps serem realizados testes, os
resultados dos testes devem ser tambm includos.

2.4 Comentrio de linha: Devem ser colocados comentrios de linha apenas em zonas complexas, de
forma a complementar a descrio do algoritmo feita no comentrio de mtodo. Os comentrios de linha
devem assumir que o leitor conhece a linguagem de programao, pelo que no devem repetir o que est
no cdigo.

Exemplo C++:
O primeiro comentrio desnecessrio, uma vez
que suposto antes de ler este mtodo tenha sido
lida a definio de classe onde estar definido a. O
nome do mtodo tambm suficientemente
sugestivo, pelo que o comando no necessita de
comentrio.

O segundo comentrio correcto pois explica o


algoritmo de forma simples, com um exemplo, e no
repete o que j est no cdigo.

Os comentrios so sempre complicados de se escrever. Primeiro porque quando o cdigo complexo


tambm mais difcil de explicar, e em segundo porque a mente do programador est ocupada com a
estrutura de dados e com o algoritmo implementado, est mais preocupada com o facto do algoritmo
estar ou no a funcionar do que inspirada para a literatura. Por outro lado, enquanto que o cdigo
necessrio para o programa correr, os comentrios no, e podem ser sempre adicionados mais tarde,
quando houver tempo. J os comentrios curtos junto a atributos e mtodos o problema de outra
natureza: encontrar uma frase de uma s linha que adicione algo ao prprio nome do atributo ou mtodo.
complicado, mas tem que ser. Os comentrios mais difceis de escrever so os que no podem ficar
para depois. Se isso acontecer o mais provvel que o prprio autor se veja ele prprio a olhar
novamente para o cdigo que escreveu dias antes a tentar compreend-lo, e a considerar a hiptese de
re-escrever o cdigo todo de novo.

3. Nomes

3.1 Variveis iteradoras inteiras: Os nomes das variveis devem comear por letras minsculas. As
variveis iteradoras inteiras devem ser chamadas i, j e k. Devem ser reutilizadas, devendo o k ser
utilizado apenas se o i e j estiverem em utilizao. Caso sejam necessrias mais que trs variveis
www.moodle.univ-ab.pt//print.php?id 30/85
26-01-2010 name
iteradoras, adicionar um nmero letra i (i1, i2, ...). Caso as variveis iteradoras sejam reais ou de outra
natureza, utilizar as letras l, m e n.

3.2 Variveis no iteradoras: Para as variveis no iteradoras deve-se utilizar nomes elucidativos. Na
juno de dois nomes, a letra inicial do segundo nome deve ser maiscula. A primeira letra deve ser
sempre minscula. Caso no existam nomes elucidativos, utilizar as letras u, v e w para os valores
inteiros, x, y e z para os valores reais, a, b e c para nomes (strings), e p, q e r para apontadores ou
variveis de outra natureza.

3.3 Constantes e macros: Constantes ou macros devem ser escritos em maisculas, e as palavras
separadas por um "underscore": '_'.

3.4 Estruturas e classes: Os nomes das estruturas ou classes tm de ter sempre nomes elucidativos e
devem comear por T se um tipo abstracto de dados, S se for uma estrutura, e C se for uma classe no
geral, D se for uma classe para caixas de dilogo de uma interface grfica. Na juno de dois nomes, a
letra inicial de cada nome deve ser maiscula.

3.5 Mtodos: Os nomes dos mtodos devem ter sempre nomes elucidativos. No caso de programao
no orientada por objectos, o nome das funes e procedimentos deve ser antecedida do nome ou
iniciais do mdulo a que pertencem. Na juno de dois nomes, a letra inicial de cada nome deve ser
maiscula. No utilizar o mesmo nome para funes ou mtodos com argumentos diferentes, a no ser
que as funes ou mtodos sejam apenas diferentes verses. Em princpio, o nome de um procedimento
deve conter um verbo no infinitivo, enquanto que o nome de uma funo dever ter o nome da grandeza
que calcula, no necessitando de verbo. As funes com resultado booleano devem conter um verbo no
presente ou adjectivo de forma a serem utilizadas dentro de condicionais.

Os nomes so parecidos com os comentrios: difceis de obter, essenciais para a compreenso do


cdigo, irrelevantes para a execuo. J o tamanho no afecta a produtividade nem cria problemas de
haver enganos a escrever. O ambiente de desenvolvimento auxilia e verifica a escrita dos nomes de
atributos e mtodos, no h motivo para se utilizar iniciais ou abreviaturas.

4. Estilo

4.1 Blocos de cdigo: No abrir um bloco de cdigo para um s comando, excepto para evitar confuso
por exemplo numa cadeia if/else.

Exemplo C++:
O bloco de cdigo criado para o ciclo for
desnecessrio uma vez que tem apenas um
comando.

O bloco de cdigo do primeiro if necessrio para


esclarecer que o else do primeiro if e no do
segundo. O bloco de cdigo do else
desnecessrio, mas considera-se razovel uma vez
que o if correspondente tem tambm um bloco de
cdigo para um s comando.

www.moodle.univ-ab.pt//print.php?id 31/85
26-01-2010 name

4.2 Repeties: No repetir uma sequncia de comandos. Muitas vezes por facilidade ao escrever
cdigo, repetem-se comandos quando poderiam ser postos dentro de um ciclo.

Exemplo em C++:
A segunda implementao da funo taxa
prefervel primeira, uma vez que o teste sempre
o mesmo e pode ser colocado dentro de um ciclo.
Por vezes no s um comando repetido mas sim
vrios comandos que poderiam estar dentro de um
ciclo, com eventualmente recurso a um ou mais
vectores estticos com os argumentos que sejam
necessrios.

4.3 Tamanho dos mtodos: No fazer mtodos demasiado grandes (mais de 100 linhas de cdigo).
Nesse caso agrupar comandos relacionados em mtodos, mesmo que o mtodo venha a ser chamado
uma s vez.

4.4 Comandos numa linha: Iniciar sempre uma nova linha para um comando, ou seja, no colocar antes
de um comando um condicional, ciclo, ou outro comando.

Exemplo em C++:
Os dois comandos do if/else deviam estar em linhas
diferentes.

Exemplo: Poker

As vantagens de um Ambiente de Desenvolvimento, so difceis de se colocar em texto, mesmo com um


exemplo concreto. prefervel que seja o estudante a descobrir por s prprio. Para tal h duas vias que
se sugere, que dever optar conforme o tempo disponvel para estudo:

1. Implementar o exemplo com base no cdigo reutilizado NewEngine.zip e na documentao


existente ( o cdigo genrico de um novo algoritmo, disponvel no EngineTester que no
necessrio instalar agora);
2. Partir do cdigo implementado Cartas.zip e aplicar as normas de escrita de cdigo.

A segunda via claramente mais simples e menos real que a primeira via, mas entre no fazer nada no
Ambiente de Desenvolvimento, prevervel ao menos re-escrever cdigo, que poder mesmo assim
colocar o estudante em situaes em que lhe sero teis os mecanismos de facilitao de leitura, escrita e
depurao do cdigo.

Este exemplo do Poker tem cdigo reutilizado, o TVector, enquanto que o TEngine apenas tenha a sua
utilidade clarificada no captulo do EngineTester. Por agora pode ser visto como uma forma de poupar a
escrita da interface com o utilizador, que embora seja de texto, d sempre algum trabalho. A classe
TCartas pode ser vista como uma classe a ser reutilizada em outras aplicaes de cartas, pelo que as
preocupaes em escrever cdigo reutilizvel devem ser consideradas para esta classe.

Aps realizar esta actividade, pela via 1 ou 2, coloque o cdigo no frum de estudante, e veja o cdigo
dos seus colegas. Pode ver o nvel de diferenas que duas implementaes com a mesma especificao e
desenho podem atingir, e por outro lado, a dificuldade que poder ter em ler o cdigo de um colega,
www.moodle.univ-ab.pt//print.php?id 32/85
26-01-2010 name
mesmo tendo acabado de implementar uma aplicao idntica.

Exemplo: Poker, alterao 1

Vamos agora simular uma primeira alterao especificao, e respectiva resoluo passo a passo. Se
quiser resolva primeiro e s depois veja a resoluo.

Pretende-se calcular a frequncia absoluta de ocorrncia de cada tipo de mo, devendo essa
informao ser guardada de forma a ser retornada no mtodo TCartasEngine::Indicator

De forma a simular uma situao real, esta actividade no deve ser realizada logo aps a actividade
anterior. Deve fazer uma actividade formativa de outra unidade curricular, e s depois continuar. O
objectivo desta actividade no apenas reflectir a alterao no cdigo, mas faz-lo do modo mais rpido
e seguro, numa altura em que j tem a cabea em outro projecto, utilizando para tal funcionalidades
disponveis no Ambiente de Desenvolvimento. Quem no fez a actividade anterior, pode realizar esta,
partindo do cdigo da via 2 (Cartas.zip).

A - Recepo do Cdigo

H que ter alguns cuidados ao receber cdigo de outras pessoas, nomeadamente conveniente estes trs
passos:

O cdigo compila? Este o primeiro passo. Se no compilar pode ser um problema de


diferenas entre compiladores, ou ento houve um engano nos ficheiros que foram enviados.
Apenas muito raramente o motivo ser de a pessoa nem sequer ter compilado o cdigo que
enviou, e mesmo nesse caso no h problema, uma vez que o tempo gasto foi relativamente
reduzido. Se a mesma pessoa reincidir que conveniente chamar ateno.
O cdigo faz o que suposto? claro que esta pergunta no se consegue responder porque o
cdigo pode ter bugs, mas basta um pequeno teste para ter como referncia, e que verifique as
diferentes funcionalidades pelo menos uma vez, e confirmar que o cdigo na origem, para o
mesmo input est a ter o mesmo output que o cdigo recebido. Se no for esse o caso, ento
poder haver diferenas no compilador e h que localiz-las. Sem exactamente o mesmos
resultados, no vale a pena avanar. Caso nem sequer o teste tenha sido enviado, ento h que
ped-lo.
O cdigo est a funcionar, h que guardar um backup com o teste pronto a correr, e passar ento
para a fase seguinte. Se o cdigo recebido for alterado, conveniente que se possa facilmente
voltar a trs sem ter que passar pelos dois pontos anteriores. Este backup importante tambm
em alturas em que ao corrigir bugs se desconfie do cdigo recebido, de forma a ter a possibilidade
de fazer um teste no cdigo original, colocando o input que gera o bug. Caso no se repetisse do
bug apenas no cdigo recebido, ficaria sempre a dvida se o bug teria realmente origem no cdigo
original ou se era devido sua m utilizao ou modificaes posteriores.

No trabalho, o cdigo so os ficheiros cpp e h, pelo que no Visual C++ 2008 Express Edition h que
criar um novo projecto com estes ficheiros e mandar correr, tal como no tuturial.

Pode-se verificar se os ficheiros esto todos, aps o qual manda-se correr (F5). Dever compilar e de
seguida o programa inicia. Caso no tivesse escolhido Console Application Project, daria um erro e o
programa no corria.

Para saber se est tudo bem, escreva:

set seed 1

www.moodle.univ-ab.pt//print.php?id 33/85
26-01-2010 name
set information 1
set limit states 1
run

O programa deve apresentar o seguinte output:

Comuns: [ 8 7 R93 ] nada [ R 9 8 7 3 ]


Jogador 1: [ R8 A7 R93 ] par [ R R A 9 8 ]
Jogador 2: [ 8 5 D7 R93 ] nada [ R D 9 8 7 ]
Jogador 3: [ 8 R8 7 R93 ] dois pares [ R R 8 8 9 ]
Jogador 4: [ 8 7 R9543 ] cr [ R 9 5 4 3 ]Run end.

Neste caso no h integrao do cdigo, parte-se de um cdigo e pede-se para fazer uma alterao.

B - Alterao ao Cdigo

Tendo um cdigo a funcionar, feito por outra pessoa ou pelo prprio j h bastante tempo, pretende-se a
correco de um bug, ou uma pequena nova funcionalidade.

A abordagem mais convencional consultar toda a documentao de forma a ter a ideia global da
aplicao. Caso a alterao seja pequena no sequer necessrio a compreenso global do cdigo,
desde que se mantenha o focus no que necessrio fazer. Por outro lado, como regra geral deve-se
manter o cdigo desenvolvido o mais pequeno quanto possvel, o que leva a que se reutilize a maior
quantidade possvel de cdigo existente, pelo que algum conhecimento do que existe deve ser mantido.

Segue-se o raciocnio de uma possvel abordagem, que tenta minimizar o cdigo alterado, e tambm o
cdigo consultado. S analisado o cdigo que tem de ser, e tudo o resto ignorado. As alteraes no
podem no entanto ser cegas, so sempre baseadas em evidncias. Alteraes cegas do origem a bugs e
muito tempo perdido, pelo que vale sempre a pena consultar mais cdigo para ter uma evidncia antes de
tomar a deciso de alterar algo.

1. Identificar o que tem que ser feito, a resposta pergunta: o que deve o sistema fazer de novo?
Tem que estar claro este ponto, caso contrrio no vale a pena comear. Se for possvel assentar
a resposta no teste que existe ao cdigo, melhor. No trabalho, tem que se contar quantas mos
ocorreram de cada tipo a cada jogador. H evidncia que j existe uma funo que calcula o tipo
de mo, uma vez que essa informao colocada no exemplo (nada, par, etc).
2. Estrutura de dados. O que o sistema tem que guardar? No trabalho um contador (portanto um
inteiro) por cada tipo de mo. Quantas mos existem? Basta procurar no cdigo caso no tivesse
essa informao j no enunciado. Poderia-se procurar por nada (Ctrl+F nada) e encontrava-
se um vector, alis dois vectores de nome poker com as vrias mos possveis, ou seja, 10 tipos
de mos. portanto suficiente um vector de inteiros de tamanho 10.
3. Onde guardar os dados? Tem que ser num local onde se possa aceder nos diversos locais. O
enunciado diz-nos que se tem que se devolver o resultado no mtodo TCartasEngine::Indicator,
pelo que os dados tm que ser acediveis a partir desse mtodo, mas a simulao no feita neste
mtodo, pelo que os dados no podem ser locais. S podem ficar ento na classe do mtodo,
TCartasEngine.
1. Criao da estrutura de dados. No Visual Studio h a possibilidade de adicionar variveis a
objectos atravs de wizard (na Class View, boto de contexto em cima da classe: Add
Add variable variable type = long [10] variable name = contador).
2. Caso se reutilize a estrutura de dados presente no cdigo, seria necessrio rever a sua
utilizao. Neste caso a classe TCartasEngine no tinha quaisquer dados, pelo que criou-se
a estrutura que era necessria.
www.moodle.univ-ab.pt//print.php?id 34/85
26-01-2010 name
3. Convm colocar um comentrio em todas as zonas alteradas, referenciar a alterao com
um cdigo (ou a data de alterao), para no caso de se querer saber o que foi feito para
determinada alterao ao cdigo se localizar facilmente as linhas alteradas.
4. Inicializao da estrutura de dados. Onde se inicializa o contador? A primeira resposta : no
construtor da classe. No entanto, no construtor da classe h um s comando, uma chamada ao
mtodo Reset(). A interpretao clara: esta classe tem a inicializao dos dados num mtodo
que no o construtor, de forma a poder reinicializar quando for preciso. Mantendo a filsofia, h
que colocar a reinicializao no mtodo Reset, mas se no entanto se colocar no construtor no
estaria incorrecto. A inicializao neste caso a colocao da estrutura a zero: for(int
i=0;i<10;i++) contador[i]=0;
5. Actualizao dos dados. Onde se incrementa o contador?
1. H que localizar o cdigo onde a mo calculada. Um bom ponto de partida descobrir o
local onde mostrada a informao para a consola: Ctrl+F Jogador, aps algumas
iteraes localizavam-se as linhas onde tal informao disponibilizada:
i. fprintf(stdout,"\nJogador %d: ",i+1);
ii. m[i].Save(stdout);
iii. m[i].SaveSolution(stdout);
2. Dado que aparece na consola a mo deste jogador, evidente que no objecto m[i] est j
o resultado da mo, ou ento esta calculada numa destas funes. Que tipo o objecto
m[i]? Basta parar o rato em cima da varivel e o Visual Studio diz, no h necessidade de
andar para cima e para baixo com a scrollbar: TVector<TCartas>, sendo portanto um
elemento do tipo TCartas. H que investigar esses dois mtodos, um deles dever utilizar o
vector poker, que contem os textos dos tipos de mos.
3. No mtodo SaveSolution encontra-se a utilizao do vector poker, com o argumento sendo
a chamada a um mtodo Poker(). Este mtodo deve portanto retornar o tipo de mo que
um objecto TCartas tem.
4. H agora que localizar a linha de cdigo em que o vector m ficou actualizado com as mos
de cada jogador. Colocando o cursor no cdigo da linha 5.a.i, basta procurar a anterior
referncia a m[ (Ctrl+Shift+I m[ , para continuar a recuar, continuar a carregar em
Ctrl+Shift+I). Onde a varivel aparecer numa situao de acesso no interessa, queremos a
ltima alterao, o que s pode acontecer atravs de uma atribuio ou chamada a um
mtodo. A primeira destas alteraes na linha: m[i].Poker();
5. Este mtodo j conhecemos, o que devolve o ndice da mo, os comentrios e cdigo
envolvente clarificam que se localizou o local correcto, pelo que pode-se fazer a alterao
da estrutura pretendida, a actualizao do contador: contador[m[i].Poker()]++;
6. Utilizao dos dados. No mtodo indicador basta retornar o valor do contador com base no
indicador recebido, testando eventualmente primeiro para ver se o indicador est dentro dos
limites do vector: if(indicador>=0 && indicador<10) return contador[indicador];
7. Compilar e Testar: h que repetir o teste, e utilizar a interface para obter o resultado pretendido.
Analisando o texto de ajuda, verifica-se que para pedir o indicador 3 tem que se escrever: get
indicator 3. O resultado a descrio da ajuda novamente, e lendo com mais ateno verifica-se
que h um comando para saber o nmero de indicadores: get indicators. O resultado 0. Falta
portanto definir os 10 indicadores que fizemos.
8. Corrigir. Procurando no cdigo onde indicado o nmero de indicadores, acabaria-se por
encontrar na funo main esse cdigo, em que o nmero de indicadores : engine-
>indname.Count(). O objecto engine do tipo TEngine, pelo que seguindo para a definio da
varivel obtem-se na classe a informao que os dois tvectors de strings indname e inddesc, tm
os nomes e descries dos indicadores. Estes dados tm de ser inicializados, e no foram, pelo
que tem que se ir novamente ao mtodo TCartasEngine::Reset para inicializar tambm estes
vectores com o tipos das mos. Bastar reutilizar o ciclo j feito e incluir tambm a adio de

www.moodle.univ-ab.pt//print.php?id 35/85
26-01-2010 name
novas linhas (objectos TVector esto a ser utilizados no mesmo mtodo que serve de exemplo,
para adicionar um novo elemento basta chamar o mtodo Add): indname.Add(poker[i]);
inddesc.Add(poker[i]);. Se se quiser pode-se fazer um novo vector com as descries dos tipos
das mos.
9. Compilar e Testar: repetir o teste e aps terminar efectuar o comando: get indicator 1, get
indicator 2, etc. Verificar que o nmero devolvido coincide com o nmero de tipos de mos
obtidos pelos jogadores no teste. Fazer um segundo teste com maior volume, por exemplo:
1. set information 0
2. set limit states 1000
3. run
4. (aguardar que acabe)
5. get indicator 1
6. get indicator 2
10. H evidncia que a alterao foi correctamente bem feita, o prximo passo enviar o cdigo a
algum que o teste.

Quantas alteraes foram necessrias?

Criar o contador em TCartasEngine


Inicializar o contador (e posteriormente os indicadores) em TCartasEngine::Reset
Actualizar o contador em TCartasEngine::Run, alterando uma linha de cdigo
Retornar o resultado do contador em TCartasEngine::Indicator

"Software Engineering, theory and practice", second edition, Prentice Hall, Shari Pfleeger, pg. 307, 319-
320

www.moodle.univ-ab.pt//print.php?id 36/85
26-01-2010 name

5 - Testes
5.1 Introduo
A fase de teste no se destina a provar que o cdigo est correcto, uma vez que tal no possvel. O
objectivo da fase de teste encontrar falhas, e por mais cuidadoso que os programadores tenham sido
na fase do cdigo, juntamente com os intervenientes anteriores nas fases de especificao e desenho, as
falhas vo existir. No entanto no se pode efectuar as restantes fases de forma relaxada, assumindo que
na fase de testes qualquer problema ser encontrado. Se assim acontecer, a fase de testes encontrar
demasiadas falhas, e o custo do projecto ser muito superior.

Os testes so feitos de forma a verificar se os requisitos e o desenho so satisfeitos. Podem ser feitos
testes de unidades, a cada componente, e testes de integrao a diversos componentes, sendo feito um
teste final a todo o sistema. Ao encontrar uma falha h que clarificar as condies em que a falha ocorre,
para que possa ser repetida e seja relativamente simples de localizar o componente defeituoso. Por esse
motivo, manda o bom senso efectuar testes de unidades e s depois os testes envolvendo mais
componentes, de forma a ser facilmente localizada a origem da falha. Aps estes testes terem sido
realizados com sucesso, que so testes de funcionalidades, h que fazer testes de performance, e testes
de aceitao. Neste captulo sero vistas tcnicas e boas prticas para a realizao de testes.

5.1.1 Classificao Ortogonal de Defeitos


H duas grandes classes de erros, os sintcticos e os semnticos. Os erros sintcticos so os que
derivam da escrita incorrecta da linguagem. Por exemplo, na linguagem C declarar uma funo dentro de
outra funo ou abrir um bloco de cdigo e no o chegar a fechar. Este tipo de erros so detectados no
prprio editor do ambiente de desenvolvimento, sendo os de menor importncia. Os erros semnticos
so erros que apesar de no inviabilizarem o cdigo como um cdigo vlido na linguagem de
programao em uso, vo fazer com que o cdigo possa no fazer o que suposto. Por exemplo, utilizar
uma varivel sem a inicializar, ou ao ordenar um vector deixar o primeiro elemento por ordenar. Este tipo
de erros so mais difceis de apanhar, e aqui que se centra a nossa preocupao.

Antes comear procura de defeitos, podemos questionar como so os defeitos? Do que que
andamos procura? A IBM construiu uma classificao ortogonal para os defeitos, de forma a
conhecer-se um pouco mais do que se procura nesta fase, e tentar desta forma orientar os testes:

Funo - defeito que afecta funcionalidades do sistema


Interface - defeito na interface do utilizador
Validao - defeito na validao da correco dos dados correctamente antes de estes serem
utilizados
Atribuio - defeito na estrutura de dados ou inicializaes
Sincronizao - defeitos que envolvam recursos em tempo real
Documentao - defeitos na documentao
Algoritmo - defeito na eficincia e correco do algoritmo ou estruturas de dados

Adicionalmente, um defeito diz-se de omisso caso seja derivado de algum aspecto em falta no cdigo
(exemplo: varivel no inicializada). Um defeito diz-se de no omisso caso seja derivado de algum
aspecto errado no cdigo (exemplo: varivel inicializada para o valor errado).

Os defeitos de omisso detectados automaticamente pelos ambientes de desenvolvimento, so


tipicamente a no inicializao de variveis, e a no utilizao de uma varivel aps atribuir um valor.

www.moodle.univ-ab.pt//print.php?id 37/85
26-01-2010 name
Nestes casos faltar ou uma inicializao ou uma utilizao da varivel atribuda. Os defeitos de no
omisso so a maioria dos erros detectados, tipicamente os sintacticamente incorrectos.

5.1.2 Organizao dos Testes

Os testes so feitos a diversos nveis, e por diferentes intervenientes. O primeiro teste feito pelo
programador na fase de implementao. Actualmente os ambientes de desenvolvimento permitem ter o
cdigo sempre pronto a correr, de forma a se ir testando o que se vai fazendo. Desta forma fcil aps a
escrita de um mtodo verificar se est a funcionar. Um teste maior ser feito pelo prprio programador
aps toda a classe estar implementada. Assim o programador pode detectar problemas cedo e corrigir
de imediato, uma vez que sabe que a origem do problema muito provavelmente no cdigo que acabou
de escrever. Um teste a uma classe ou mdulo, chama-se teste de mdulos, ou teste de componentes, ou
ainda teste de unidades. Deve ser realizado tambm por uma pessoa diferente da que implementou o
mdulo.

Os componentes vo ficando prontos, e aps estes terem passado o teste de unidades, h que executar
um teste de integrao envolvendo mais que um componente, de forma a verificar que os diversos
componentes interagem da forma correcta.

Aps os testes de integrao h que efectuar testes a todo o sistema. O primeiro o teste funcional que
consiste em testar o sistema para verificar se est de acordo com os requisitos funcionais. De seguida h
que efectuar o teste de performance, de forma a verificar os requisitos no funcionais. O teste seguinte
o de aceitao, que envolve o cliente e verifica os requisitos do cliente. Finalmente instala-se o sistema no
seu local final e efectua-se um teste de instalao com utilizadores finais.

Uma falha em qualquer documento pode ser encontrada em qualquer altura. Salienta-se o facto de os
primeiros documentos a produzir serem os ltimos a testar, e portanto a verificar. O pior que poderia
acontecer seria a documentao tcnica de requisitos no estar coerente com os requisitos do cliente.
Caso a incoerncia no fosse detectada antes seria apenas no teste de aceitao, ou seja, numa fase
muito terminal do projecto, o que poderia obrigar a refazer tudo de novo. portanto natural que seja
atribuda a responsabilidade das fases iniciais do projecto s pessoas com mais experincia.

Quando o componente testado por outra pessoa, ao encontrar uma falha a preocupao dever ser a
de conseguir repetir a falha e report-la para que esta seja corrigida, e no propriamente de culpar a
pessoa que desenvolveu o componente.

5.2 Tipos de Testes


5.2.1 Teste de Unidade
Este teste tambm chamado de teste de mdulo ou teste de componentes. H basicamente trs testes
de unidades que se pode fazer:

Reviso de cdigo;
Provas matemticas;
Testes empricos.

A primeira via permite envolver recursos humanos no teste, tirando assim proveito em que pessoas
experientes detectam falhas muito rapidamente, mas por outro lado tm um custo elevado. A segunda via
requer que quem faa o teste tenha muito tempo e bases matemticas, e estas provas tm tambm de ser
verificadas, uma vez que tambm podem ter erros. A terceira via a mais utilizada, tambm

www.moodle.univ-ab.pt//print.php?id 38/85
26-01-2010 name
complementar das anteriores. Consiste em efectuar testes empricos atravs de execues do cdigo em
teste, e comparar os argumentos com os resultados de forma a verificar se os resultados esto correctos.
O teste analisa uma amostra das possveis execues que o cdigo pode originar, permitindo assim
verificar se funciona bem nessa amostra e por outro lado efectuar desde logo testes de performance.
Convm que a amostra seja representativa da populao, pelo que a escolha dos dados de teste
determinante. A dimenso da amostra ser dependente do tempo de execuo de cada corrida e do
tempo disponvel para todo o teste do componente.

Uma de duas filosofias pode ser utilizada na escolha de dados de teste: caixa preta (ou caixa fechada);
caixa branca (ou caixa aberta). No teste efectuado como caixa preta os dados de teste so escolhidos
sem fazer uso da implementao do objecto de teste, e so normalmente gerados aleatoriamente. O teste
em modo de caixa branca consiste em escolher os argumentos com base na anlise da estrutura interna
do componente, permitindo assim escolher uma amostra mais representativa de todas as execues que
podem ser efectuadas com o componente.

Os argumentos do teste so o conjunto de todas as variveis que se tem de inicializar para testar o
componente. No caso de serem muitas variveis torna-se complicado testar todas as combinaes.
Normalmente prefervel em caixa preta seleccionar uma distribuio para cada varivel. Caso as
variveis tenham um valor mnimo e mximo pode-se utilizar a distribuio uniforme, mas caso no
tenham limite pode-se utilizar por exemplo a distribuio exponencial negativa. Esta distribuio tem
probabilidade de gerar um valor muito elevado, muito embora tenha mais probabilidades de gerar um
valor perto do zero. Tem uma forma simples de ser gerada a partir da distribuio uniforme: -
log(Uniforme(0;1))

Em caixa branca o cdigo analisado e pode-se querer garantir que durante a execuo de todo o teste
as diversas situaes so testadas:

Teste de comandos: cada comando executado pelo menos uma vez;


Teste de ramificaes: em cada ponto de deciso no cdigo, cada ramo tomado pelo menos
uma vez;
Teste de caminhos: cada sequncia de comandos (caminho) no cdigo executada pelo menos
uma vez;
Teste de todas as utilizaes: pelo menos um caminho da definio a todas as utilizaes da
varivel tem de ser executado pelo menos uma vez;
Teste de caminhos definio-utilizao: para todas as definies de variveis e utilizaes de
variveis, todos os caminhos da definio utilizao da varivel, devem ser executados pelo
menos uma vez.

Se o cdigo for complexo poder ser difcil obter os dados de entrada para se garantir que se verifique
qualquer uma destas situaes. Pode-se naturalmente combinar a caixa branca com a caixa preta,
utilizando parte do teste valores que garantem por exemplo que todos os comandos so executados, e o
resto dos valores gerados aleatoriamente.

5.2.2 Reviso de Cdigo

Uma reviso de cdigo um de teste de unidade em que o cdigo e a documentao associada so


analisados por um ou mais especialistas, de forma a se encontrarem erros de qualquer natureza. O
objectivo descobrir erros, no de os corrigir.

Uma reviso de cdigo pode ser de "walkthrough" ou inspeco de cdigo. No "walkthrough" quem
escreve o cdigo tem de apresentar equipa de reviso o seu cdigo, conduzindo a discusso de forma

www.moodle.univ-ab.pt//print.php?id 39/85
26-01-2010 name
informal, centrando-se a ateno no cdigo e no no programador.

Na inspeco de cdigo, a equipa de reviso tem de preparar uma lista de preocupaes as quais tem
de as verificar sobre a documentao e cdigo, por exemplo: definio da estrutura de dados est
consistente com a documentao de desenho; os comentrios no cdigo esto consistentes com o cdigo
que comentam; estimar a complexidade temporal e espacial do cdigo. O prprio programador pode
no fazer parte da equipa de reviso.

As revises de cdigo permitem a deteco de erros mais cedo, e portanto reduzindo a influncia desses
erros que teriam um custo muito maior para serem identificados mais tarde, e tambm um maior custo de
correco. Muitas das vezes no se fazem revises de cdigo porque as equipas de desenvolvimento de
software so pequenas, ou todas as pessoas esto atarefadas, ou ainda por ser muito cansativo analisar
cdigo feito por outros. O ganho de revises de cdigo pode no entanto ser muito elevado, se os
programadores passarem a ter mais cuidado no cdigo que escrevem, uma vez que vai ser analisado por
outros, e respectiva reduo no nmero de erros.

5.2.3 Testes de Integrao


Os diversos componentes de um sistema interagem uns com os outros, criando uma rede de
dependncias. Como h normalmente muitos componentes, essencial que exista uma estratgia de
testes de integrao de forma a testar subsistemas antes de todo o sistema, caso contrrio no s
aparecem muitas falhas em simultneo, como se torna difcil localizar a origem das falhas.

A primeira estratgia de teste a de baixo-para-cima. Nesta estratgia cada componente que


completamente independente dos restantes, inicialmente testado separadamente. De seguida, os
componentes cujos seus componentes dependentes j esto testados, devem ser testados utilizando
esses componentes. O processo repete-se at que no no fim todo o sistema ser testado. Caso existam
dois ou mais componentes que dependam mutuamente entre si, esses componentes devem ser testados
em conjunto. Para testar um componente sem ser atravs dos componentes que o utilizam, necessrio
programar uma rotina chamada driver (component driver), que ir fazer as inicializaes necessrias
para correr o componente com os dados de teste. Os drivers so normalmente simples de codificar, e a
determinao dos dados de teste debatida no teste de unidade. Esta estratgia assenta bem na
programao orientada por objectos, mas tem o problema de as falhas mais importantes, as que ocorrem
nos componentes que utilizam mais componentes, serem descobertas apenas no final. Estas falhas so
provavelmente da fase de desenho, e devem ser descobertas o quanto antes, uma vez que podem
implicar muito trabalho para as corrigir.

A segunda estratgia de teste a de cima-para-baixo. Nesta estratgia comea-se por testar o


componente mais geral, que no utilizado por nenhum outro, e de seguida os componentes que so
utilizados apenas por componentes j testados. O ciclo continua at que todos os componentes estejam
testados. Caso existam dois ou mais componentes que dependam mutuamente entre si, esses
componentes devem ser testados em conjunto. Para testar um componente sem ter os componentes que
utiliza testados, tem de se construir um stub por cada componente utilizado, de forma a simular a sua
actividade. A simulao do componente tem de possibilitar os diversos tipos de interaces, pelo que
no deve ser algo constante. Os stubs so normalmente mais difceis de construir, e em certos sistemas
podem ser requeridos demasiados stubs o que pode inviabilizar esta estratgia. A vantagem de testar
o que mais importante primeiro, permitindo descobrir os erros que podem originar mais mudanas mais
cedo. Uma alterao a esta estratgia, consiste em testar sempre cada componente isoladamente antes
de ser testado em conjunto. Neste caso so necessrios tanto stubs como drivers.

A estratgia Big-bang consiste em testar cada componente isoladamente primeiro, e de seguida testar

www.moodle.univ-ab.pt//print.php?id 40/85
26-01-2010 name
todo o sistema. Esta estratgia necessita de stubs e drivers e tem a desvantagem de ser complicado
localizar a origem das falhas no teste geral. possvel utilizar-se esta estratgia apenas em pequenos
sistemas.

A estratgia Sandwich consiste em juntar as estratgias de baixo-para-cima e de cima-para-baixo.


Pode-se aplicar uma das estratgias apenas at um determinado nvel, e a outra encarrega-se de testar o
resto, e desta forma tem-se o melhor de dois mundos. No se deve descer muito com a estratgia de
cima-para-baixo para no ter que codificar uma grande quantidade de stubs, mas convm descer at
um nvel que permita detectar falhas no desenho do sistema.

5.2.4 Teste de Performance

Os testes de unidade e testes de integrao so direccionados a verificar se o cdigo est de acordo com
o desenho. O teste do sistema destina-se primeiramente a verificar se todo o sistema est de acordo com
os requisitos funcionais, de seguida efectuam-se testes de performance para verificar os requisitos no
funcionais, seguindo-se o teste de aceitao envolvendo o cliente e teste de instalao no ambiente do
utilizador final.

Os testes de performance devem ser efectuados conforme os requisitos no funcionais. Os mais comuns
so:

Teste de stress o sistema testado at aos limites especificados, num pequeno espao de
tempo, simulando um pico de utilizao;
Teste de volume grande volume de dados fornecido ao sistema, de forma a verificar se
responde correctamente quando tem demasiados dados;
Teste de velocidade verifica os tempos de resposta do sistema;
Teste de configurao so feitos testes com diferentes configuraes no software e no hardware;
Teste de compatibilidade so executados se o sistema necessitar de interagir com outros
sistemas;
Teste de regresso necessrio quando o sistema substitui outro sistema. Tem que se assegurar
que as funcionalidades anteriores esto implementadas no novo sistema;
Teste de segurana verifica a segurana do sistema.

Estes testes so chatos de se fazerem, e muitas das vezes so substitudos pela garantia do
profissionalismo e competncia da empresa que desenvolve o software. No apresenta ao cliente
relatrio de testes algum, o prprio cliente no pediu este relatrio, apenas quer o sistema a funcionar e
contenta-se com uma demonstrao do sistema. Se o sistema falhar durante a demonstrao, haver
certamente um conjunto de explicaes que o cliente no percebe e por isso fica satisfeito.

medida que o tempo passa, quando o sistema for sendo cada vez mais utilizado o cliente vai-se
apercebendo do que est mal no sistema, atravs das queixas dos utilizadores: "s X horas, quando
todos tentam aceder o sistema no responde", "no funciona quando se quer introduzir uma ficha com
mais de Y campos", "o sistema lento", "no funciona em computadores com o Sistema Operativo W",
"aps a ltima actualizao, j no se consegue introduzir uma ficha do tipo K, nem imprimir", "o
utilizador convidado, mesmo sem permisses consegue ver e editar as fichas". Nessa altura o cliente paga
empresa a manuteno que o sistema necessitar.

A imagem da empresa provavelmente no posta em causa. O sistema simplesmente muito complexo,


e durante os testes no se poderiam prever todas as situaes. Esta frase correcta, mas no invalida
que se faam estes testes e se apresente um relatrio de testes ao cliente para o comprovar. Sem estes
testes o sistema iniciar-se- com problemas que poderiam ser detectados pela equipa de

www.moodle.univ-ab.pt//print.php?id 41/85
26-01-2010 name
desenvolvimento de software.

5.2.5 Teste de Aceitao

Os testes de aceitao so feitos de acordo as preferncias do cliente. O cliente pode fazer um conjunto
de testes a efectuar, com as situaes tipo em que o sistema ser utilizado, de forma a verificar no s
que o sistema funciona bem como tambm a avaliar a performance do sistema. Normalmente efectua-se
tambm testes piloto, em que os utilizadores utilizam o sistema nas condies finais. Caso os utilizadores
sejam da empresa, o teste piloto chama-se de teste alfa, se os utilizadores forem os finais, chama-se
teste beta.

Aps o teste de aceitao terminar, o cliente dever dizer quais os requisitos que no esto satisfeitos, e
quais os que devem ser apagados, revistos ou adicionados.

5.2.6 Documentao de Teste


O volume da documentao de teste deve ter uma dimenso adequada aos testes produzidos e ao
sistema testado. Um sistema de mdia grande dimenso deve ter os documentos:

Plano de teste - deve descrever o sistema e os testes a efectuar para verificar os requisitos;
Especificao de teste - deve conter os requisitos testados e como so testados;
Descrio de teste deve definir os dados de teste e os procedimentos de teste;
Relatrio de teste deve descrever os resultados obtidos.

5.3 Quando parar de testar


5.3.1 Alternativas
No havendo forma de saber se um componente tem ou no erros levanta-se a questo de saber quando
parar de testar. Essa deciso deve ser de gesto, uma vez que continuar os testes incorre-se em mais
custos de recursos humanos, mas aumenta-se a fiabilidade do software. Para suportar essa deciso h
que conseguir estimar o nmero de falhas e o grau de confiana no software de alguma forma.

Uma hiptese inserir falhas no software, que deve ser feita por algum da equipa de teste, mas que no
participa no teste. Inserindo-se por exemplo S=20 falhas, caso a equipa de teste encontre s=15 dessas
falhas e mais n=10 falhas diferentes, ento pode-se estimar o nmero total de falhas N pela frmula:
, assumindo que . Neste caso daria faltas, faltando portanto
encontrar 3,3 falhas. O problema deste mtodo que tem que se inserir muitas falhas para ter algum grau
de preciso, e as falhas devem ser da mesma natureza das que esto por descobrir. H tambm um
aumento no custo de teste.

Uma segunda hiptese utilizar duas equipas de teste independentes, descobrindo cada equipa um
nmero de falhas f1 e f2, das quais algumas falhas so iguais f12. Pode-se assumir que a eficincia de cada
equipa relativamente a descobrir o total de falhas n, ser de E1=f1/n e E2=f2/n. Pode-se estimar a
eficincia de uma equipa a descobrir as falhas que a outra equipa descobriu como sendo E1=f12/f2 e
E2=f12/f1, e portanto estimar o nmero total de falhas atravs da frmula n=f12/(E1*E2). Nesta soluo o
custo aumenta porque h falhas descobertas por ambas as equipas, mas no duplica propriamente, uma
fez que todas as pessoas envolvidas esto a testar o software. Notar no entanto que as equipas nunca
podem ser completamente independentes, uma vez que os testers tm formaes idnticas, e acabam
por ter a tendncia de descobrir as mesmas falhas.
www.moodle.univ-ab.pt//print.php?id 42/85
26-01-2010 name

Uma terceira hiptese utilizar o modelo Motorola, que nos permite saber o nmero de horas que se tem
de testar sem que nenhuma falha seja encontrada para garantir que o cdigo apenas tem um determinado
nmero de falhas. O modelo tem tambm assumpes, pelo que o valor aconselhado meramente
indicativo, e no propriamente uma certeza.

5.3.2 Modelo Motorola


O modelo Motorola permite estimar o nmero de horas de teste necessrias, sem que ocorram falhas,
para que se tenha no cdigo apenas um especificado nmero de falhas. O modelo necessita do nmero
de falhas encontradas at ao momento (falhas_identificadas), e do nmero de horas at ltima falha
(horas_at_ltima_falha).

O nmero de horas necessrias dada pela seguinte frmula:

Exemplo:

Uma falha acabou de ser encontrada, num teste que decorre h 80 horas, sendo j a 10 falha
encontrada. Foi decidido que apenas 1 falha dever ficar por identificar, e pretende-se saber quanto
tempo se ter de testar sem que apaream novas falhas para assumir que apenas existe uma falha por
descobrir.

Com estes dados podemos aplicar o modelo Motorola: ln(1/1.5)x80/ln(1.5/11) = ln(0.67)x80/ln(0.14).


Como no permitido calculadoras nos exames, fornecida a tabela do logaritmo (ver em baixo), pelo
que o nmero de horas necessrio de: 0.4x80/1.97=16 horas.

Exemplo: Poker

Vamos testar no nosso exemplo o mtodo TCartas::Poker, dado que o mtodo mais
complexo, assumindo mos de 7 cartas. O teste deve verificar se os diferentes tipos de mos so
identificados correctamente.

Caso no tenha feito as actividades anteriores, o cdigo de partida o Cartas.zip. Se quiser pode fazer
os testes apenas com esta informao, e continuar a ler apenas quando acabar, ou aceitar algumas
sugestes lendo o prximo pargrafo.

Sugesto: faa um gerador de mos de determinados tipos, e chame o mtodo para verficar se a
resposta correcta. Por exemplo, para gerar uma mo com um par, retire de um baralho um par gerado
www.moodle.univ-ab.pt//print.php?id 43/85
26-01-2010 name
aleatoriamente e adicione-o mo, e de forma a no haver mais pares nem trios, retire as restantes duas
cartas do mesmo nmero do baralho, e retire tambm trs cartas aleatoriamente de cada um dos
restantes nmeros. Para evitar sequncias, retire um dos nmeros 5 ou 6 e o nmero 10 ou V
respectivamente. Baralhe as restantes cartas e junte mo as 5 primeiras. Finalmente, para evitar a cor,
conte quantas cartas tem de cada naipe na mo, e no caso de ter 5 ou mais troque o naipe de uma das
cartas que no fazem parte do par.

Resoluo

Pretende-se testar o mtodo TCartas::Poker, pelo que tem que se ter:

1. Um gerador de mos (das 10 tipos de mos);


2. O mtodo TCartasEngine::Run tem que utilizar o gerador para gerar as mos especficas, e
verificar se o valor retornado pelo mtodo TCartas::Poker igual.

O trabalho resume-se a alterar o mtodo TCartasEngine::Run e a criar um mtodo para gerar as mos,
portanto dois mtodos.

Pode-se comear por criar o mtodo para gerar as mos em


TCartasEngine::GerarMao(TCartas&mao,int tmao,int ncartas);

No mtodo TCartasEngine::Run, h que apagar tudo e gerar as mos por ordem, verificando se esto
correctas:

void TCartasEngine::Run()
{
Seed();
// processar todos os tipos de mos
for(int i=0;i<10;i++) {
// para cada mo testar o nmero especificado de vezes
for(long j=0;j<States();j++) {
// gerar uma mo
TCartas mao;
GerarMao(mao,i,7);
int resultado=mao.Poker();
if(resultado!=i) {
// erro, a mo gerada no coincide com a calculada
printf("\n%s: #%d (%s)",poker[i],j,poker[resultado]);
mao.Save(stdout);
}
}
}
}

O gerador de mos mais complexo, tem que se ir desenvolvendo. Foi implementada uma filosofia
diferente da sugesto no enunciado, que consiste no seguinte:

Comear com um baralho com ordem aleatria;


Ir retirando as cartas que no so necessrias para a mo que se quer, bloqueando as que se
quiser manter;
No final deitar fora as cartas a mais.

www.moodle.univ-ab.pt//print.php?id 44/85
26-01-2010 name
Este mtodo acaba por ter duas zonas, as mos com numeraes idnticas, e as mos com cor e
sequncia. O cdigo torna-se um pouco mais complexo porque tem que se impedir que na gerao de
um par no aparea por engano um trio, ou no aparea cor. O cdigo completo da funo est
comentado de forma a ser melhor interpretado.

void TCartasEngine::GerarMao(TCartas&mao,int tmao,int ncartas)


{
TVector<int> bloquear;
int estado=0;
mao.Baralho();
mao.cartas.RandomOrder();

if(tmao==0 || tmao==1 || tmao==2 || tmao==3 || tmao==6 || tmao==7)


{ // nada; par; 2pares; trio; fullen; poker
for(int i=1;i<mao.cartas.Count();i++) {
if(estado==tmao && i>ncartas-1)
break;
if(i>=4 && tmao!=6 && tmao!=7) {
// impedir cor
int count=1;
for(int j=0;j<i&&j<ncartas;j++)
if(TC_NAIPE(mao.cartas[i])==TC_NAIPE(mao.cartas[j]))
count++;
if(count>=5) {
mao.cartas.Delete(i--);
continue;
}
// impedir sequncia
int de;
bool seq=false;
for(de=TC_NUMERO(mao.cartas[i])-4;de<=TC_NUMERO(mao.cartas[i]);de++) {
int j=de;
for(j=de;j<de+5;j++) {
int l;
for(l=0;l<=i;l++)
if(TC_NUMERO(mao.cartas[l])==j)
break;
if(l==i+1) break; // no h este nmero, no h problema
}
if(j==de+5) { // sequncia
mao.cartas.Delete(i--);
seq=true;
break;
}
}
if(seq) continue;
}

for(int j=0;j<i&&j<ncartas;j++)
if(TC_NUMERO(mao.cartas[j])==TC_NUMERO(mao.cartas[i])) {
if( // o estado requerido j foi atingido
www.moodle.univ-ab.pt//print.php?id 45/85
26-01-2010 name
estado==tmao ||
estado>0 && (
// ou quer-se dois pares e estava para vir um trio
tmao==2 && bloquear.Find(j)>=0 ||
// ou quer-se um trio e estava para vir dois pares
(tmao==3 || tmao==7) && bloquear.Find(j)<0 ||
// ou quer-se fullen e estava para vir trs pares
tmao==6 && estado==2 && bloquear.Find(j)<0))
{
mao.cartas.Delete(i--);
} else {
// aceitar esta carta se:
if(estado==0 ||
(tmao==3 || tmao==7) && bloquear.Find(j)>=0 ||
tmao==2 && bloquear.Find(j)<0 ||
tmao==6 && (estado<=1 ||
estado==2 && bloquear.Find(j)>=0 ||
estado==3 && bloquear.Find(j)<0))
{
if(estado==0) estado=1;
else if(estado==1)
estado=(bloquear.Find(j)<0?2:3);
else if(estado==2) estado=6;
else if(estado==3)
estado=(bloquear.Find(j)<0?6:7);
if(i>ncartas-1) {
// arranjar uma carta para trocar
for(int l=0;l<ncartas&&l<i;l++)
if(l!=j && bloquear.Find(l)<0) {
bloquear.Add(j);
bloquear.Add(l);
mao.cartas[l]=mao.cartas[i];
mao.cartas.Delete(i--);
break;
}
} else {
bloquear.Add(i);
bloquear.Add(j);
}
} else {
// no aceitar a carta
mao.cartas.Delete(i--);
}
}
break;
}
}
} else if(tmao==4 || tmao==5 || tmao==8 || tmao==9) {
// sequncia, cor, sequncia + cor, sequncia + cor real
for(int i=0;i<mao.cartas.Count();i++) {

www.moodle.univ-ab.pt//print.php?id 46/85
26-01-2010 name
// coloca as primeiras 5 cartas com o requerido, as outras so sorte
if( // apagar todas as cartas de naipe diferente
i<5 && (tmao==5 || tmao==8 || tmao==9) &&
TC_NAIPE(mao.cartas[i])!=TC_NAIPE(mao.cartas[i-1]) ||
// apagar todas as cartas baixas
i<5 && tmao==9 && TC_NUMERO(mao.cartas[i])<8 ||
// apagar os ases para impedir a sequncia + cor real
tmao==8 && TC_NUMERO(mao.cartas[i])==12 ||
// no deixar sequncia passar a cor em 5 cartas
i==1 && tmao==4 && TC_NAIPE(mao.cartas[0])==TC_NAIPE(mao.cartas[1]) ||
// no deixar cor passar a sequncia em 5 cartas
i==1 && tmao==5 && abs(TC_NUMERO(mao.cartas[0])-
TC_NUMERO(mao.cartas[1]))<=4)
{
mao.cartas.Delete(i--);
} else if(tmao==4 && i>=5) {
// no deixar a sequncia passar a cor
int count=1;
for(int j=0;j<i&&j<ncartas;j++)
if(TC_NAIPE(mao.cartas[i])==TC_NAIPE(mao.cartas[j]))
count++;
if(count>=5) {
mao.cartas.Delete(i--);
continue;
}
} else if(tmao==5 && i>=5) {
// no deixar a cor passar a sequncia
int de;
bool seq=false;
for(de=TC_NUMERO(mao.cartas[i])-4;de<=TC_NUMERO(mao.cartas[i]);de++) {
int j=de;
for(j=de;j<de+5;j++) {
int l;
for(l=0;l<=i;l++)
if(TC_NUMERO(mao.cartas[l])==j)
break;
if(l==i+1) break; // no h este nmero, no h problema
}
if(j==de+5) { // sequncia
mao.cartas.Delete(i--);
seq=true;
break;
}
}
if(seq) continue;
} else if(i<5 && (tmao==4 || tmao==8 || tmao==9))
for(int j=0;j<i;j++)
// apagar todos os nmeros que distam mais de 4 dos anteriores
if(TC_NUMERO(mao.cartas[j])==TC_NUMERO(mao.cartas[i]) ||
abs(TC_NUMERO(mao.cartas[j])-TC_NUMERO(mao.cartas[i]))>4)

www.moodle.univ-ab.pt//print.php?id 47/85
26-01-2010 name
{
mao.cartas.Delete(i--);
break;
}
}
}
if(mao.cartas.Count()>ncartas)
mao.cartas.Count(ncartas);
}

Executar e correr. Verificar que no h mos mal colocadas, mesmo fazendo 1000 testes para cada mo:

set seed 1
set limit states 1000
run
Run end.

Para verificar da necessidade de impedir, por exemplo, a cor na gerao das cartas mltiplas, pode-se
comentar a zona de cdigo correspondente (aps o comentrio impedir cor) e correr novamente:

nada: #7 (cor)[ 8 6 AR543 ]


nada: #38 (cor)[ RD10864 A ]
nada: #39 (cor)[ 83 AD1054 ]
nada: #77 (cor)[ V4 AD1076 ]
nada: #94 (cor)[ 2 AV10843 ]
nada: #130 (cor)[ 4 R10953 V ]
nada: #156 (cor)[ R10 V8652 ]
nada: #168 (cor)[ 4 AD1086 3 ]
nada: #198 (cor)[ 3 D10874 6 ]
nada: #250 (cor)[ 98432 A 10 ]
nada: #288 (cor)[ D10985 63 ]
nada: #297 (cor)[ D10754 2 A ]
nada: #324 (cor)[ V4 AD1082 ]
nada: #351 (cor)[ 10 RV942 7 ]
nada: #385 (cor)[ 106 ARV83 ]
nada: #402 (cor)[ V4 AD965 ]
nada: #405 (cor)[ RDV65 2 7 ]
nada: #417 (cor)[ RD864 A 9 ]
nada: #434 (cor)[ D10964 5 R ]
nada: #448 (cor)[ R 7 D8632 ]
nada: #455 (cor)[ V 9 AR1086 ]
nada: #504 (cor)[ 108743 AR ]
nada: #522 (cor)[ 108642 R3 ]
nada: #550 (cor)[ 7 ARD1054 ]
nada: #557 (cor)[ A 3 D10752 ]
nada: #582 (cor)[ 4 9 ARD87 ]
nada: #585 (cor)[ D 2 ARV63 ]
nada: #586 (cor)[ R V7654 9 ]
nada: #599 (cor)[ 9 3 ARV74 ]
nada: #618 (cor)[ 32 RDV65 ]
nada: #679 (cor)[ R9752 3 D ]
www.moodle.univ-ab.pt//print.php?id 48/85
26-01-2010 name
nada: #694 (cor)[ 7 V9432 R ]
nada: #703 (cor)[ R8542 A7 ]
nada: #745 (cor)[ V9 87532 ]
nada: #753 (cor)[ AD852 R10 ]
nada: #759 (cor)[ RDV97 8 6 ]
nada: #772 (cor)[ 6 2 RDV73 ]
nada: #780 (cor)[ A V10952 3 ]
nada: #783 (cor)[ 10 A V9763 ]
nada: #793 (cor)[ D 10 A8754 ]
nada: #798 (cor)[ RV1096 5 4 ]
nada: #804 (cor)[ DV1072 86 ]
nada: #829 (cor)[ R86542 A ]
nada: #852 (cor)[ 84 V10953 ]
nada: #868 (cor)[ A5432 97 ]
nada: #869 (cor)[ RD975 3 2 ]
nada: #879 (cor)[ D10852 7 6 ]
nada: #885 (cor)[ R 97542 A ]
nada: #914 (cor)[ 10 DV764 3 ]
nada: #925 (cor)[ A 4 109753 ]
nada: #926 (cor)[ V10 R8762 ]
nada: #929 (cor)[ A2 V8763 ]
nada: #932 (cor)[ A4 DV965 ]
nada: #980 (cor)[ A V 109762 ]
nada: #982 (cor)[ 6 4 A9853 ]
par: #109 (cor)[ R9 ARD75 ]
par: #155 (cor)[ 4 R10987 4 ]
par: #163 (cor)[ A8 108743 ]
par: #239 (cor)[ 4 AD842 10 ]
par: #245 (cor)[ AR853 7 A ]
par: #248 (cor)[ 5 D109853 ]
par: #258 (cor)[ AR1054 V V ]
par: #281 (cor)[ D R7643 4 ]
par: #316 (cor)[ 8 10 D10753 ]
par: #404 (cor)[ V9754 V 3 ]
par: #421 (cor)[ DV986 A D ]
par: #506 (cor)[ 7 A10982 2 ]
par: #517 (cor)[ R RDV94 A ]
par: #533 (cor)[ V D7652 D ]
par: #570 (cor)[ AR864 7 4 ]
par: #606 (cor)[ RD965 6 7 ]
par: #622 (cor)[ R5 RV1063 ]
par: #653 (cor)[ D85432 5 ]
par: #676 (cor)[ AV986 8 D ]
par: #694 (cor)[ V ADV98 5 ]
par: #773 (cor)[ V A AD1065 ]
par: #866 (cor)[ 8 V R10986 ]
par: #892 (cor)[ D9 AD654 ]
par: #920 (cor)[ 2 RD6532 ]
par: #929 (cor)[ 83 R8752 ]
par: #938 (cor)[ D A D9654 ]

www.moodle.univ-ab.pt//print.php?id 49/85
26-01-2010 name
par: #954 (cor)[ AR1042 V A ]
2pares: #5 (cor)[ D10932 9 10 ]
2pares: #104 (cor)[ R RV985 8 ]
2pares: #155 (cor)[ 6 V9864 8 ]
2pares: #184 (cor)[ D7432 D7 ]
2pares: #189 (cor)[ D8 D10852 ]
2pares: #199 (cor)[ V8 V10984 ]
2pares: #325 (cor)[ 75 A10975 ]
2pares: #418 (cor)[ D10832 108 ]
2pares: #471 (cor)[ 2 4 109742 ]
2pares: #515 (cor)[ A R ARV42 ]
2pares: #833 (cor)[ 5 AD852 A ]
2pares: #887 (cor)[ V7 V10973 ]
trio: #6 (cor)[ 5 5 AR753 ]
trio: #88 (cor)[ R10962 R R ]
trio: #190 (cor)[ 3 3 109643 ]
trio: #303 (cor)[ AV532 5 5 ]
trio: #339 (cor)[ V V ADV103 ]
trio: #341 (cor)[ 9 9 V9752 ]
trio: #463 (cor)[ A10763 10 10 ]
trio: #527 (cor)[ D D ADV84 ]
trio: #589 (cor)[ DV653 D D ]
trio: #639 (cor)[ RD1073 3 3 ]
trio: #640 (cor)[ R10653 6 6 ]
trio: #724 (cor)[ 5 V10532 5 ]
trio: #927 (cor)[ AR982 R R ]Run end.

Verifica-se a gerao de cor acidentalmente quando se pretendia gerar mos de diversos tipos, pelo
que se confirma que o cdigo para impedir a cor nas mos de numeraes idnticas essencial.

O cdigo no teve nenhum crash, e todas as mos deram o mesmo resultado que a funo geradora,
confirmando assim o bom funcionamento do mtodo TCartas::Poker.

Se fosse necessrio maior grau de certeza, o passo seguinte, para alm de aumentar o nmero de testes,
a reviso do mtodo manualmente. Ter o teste operacional muito til nesta situao porque assim
pode-se nessa fase comentar partes do cdigo que no se compreenda de forma a ver se a ausncia do
cdigo leva a resultados incorrectos.

"Software Engineering, theory and practice", second edition, Prentice Hall, Shari Pfleeger, pg. 331-
362, 371-374, 401-403, 410, 412-414, 417-426

www.moodle.univ-ab.pt//print.php?id 50/85
26-01-2010 name

6 - Testes Empricos com o Engine Tester


A motivao para a construo do software de teste de componentes e a incluso nesta unidade
curricular, por um lado a relevncia que o teste de componentes tem na qualidade do software, e por
outro lado por no existirem ferramentas especficas de testes de componentes no mercado.

Um componente bem testado pode ser utilizado com segurana tanto no prprio projecto como ser
reutilizado em projectos posteriores. um componente que ir sobreviver ao tempo. O que o tempo
extra para teste se se ir poupar um tempo indefinido a localizar e corrigir problemas que originem no
componente que ficou por testar?

O EngineTester tem duas funcionalidades principais: efectuar testes empricos em algoritmos e testar
componentes. Podem ser analisados parmetros do algoritmo, comparar vrios algoritmos e um ou mais
conjuntos de ficheiros de dados. Estas duas funcionalidades no so incompatveis. Executar um
algoritmo com diversos valores nos seus parmetros com vista a conhecer quais os valores que o
optimizam, no incompatvel a executar um algoritmo com diversos valores nos seus parmetros com
vista a saber se funciona bem em todos os valores. Depende dos indicadores que se calcular para cada
corrida, podendo at ter-se ambos os objectivos em simultneo: optimizao e teste.

O Visual c++ 2008 Express Edition no tem ferramentas dedicadas a testes de componentes. Pode-se
sempre fazer pequenos programas para testar cada componente, mas isso leva a que o custo dos testes
aumente e que quem testa o componente tenha de construir cdigo para o testar. Na soluo de teste de
componentes com o EngineTester, quem desenvolve um componente cria tambm um engine para correr
sobre o EngineTester. Quem testa o componente no necessita olhar para o cdigo mas pode efectuar
testes de volume com qualquer nmero de parmetros e indicadores de verificao, que se podem incluir
na documentao interna do componente e se podem repetir a qualquer momento sem trabalho extra,
por exemplo aps uma actualizao do componente.

O EngineTester permite encadeamento entre algoritmos, ou seja, o resultado de um algoritmo pode ser
enviado para outro algoritmo. Todos os resultados podem ser exportados em texto, para serem
posteriormente processados, mas pode-se no prprio EngineTester construir anlises grficas a partir
dos resultados, sendo essas anlises reconstruidas cada vez que os testes sejam repetidos. Eventualmente
esta funcionalidade pode ser utilizada para testes de integrao, mas como compreensvel este tipo de
testes mais complexo e depende da aplicao concreta.

Todas as parametrizaes dos testes so armazenadas em ficheiro, de forma aos testes poderem ser
repetidos facilmente. Assim, se se quiser repetir testes j efectuados devido a um melhoramento num dos
algoritmos, ou repetir os testes numa nova mquina, ou simplesmente conferir resultados relatados por
um colega, no necessrio passar pelo processo todo, basta mandar correr o documento previamente
gravado, e todas as chamadas aos algoritmos com as respectivas parametrizaes e ficheiros de dados,
sero executadas novamente. Se os grficos forem feitos no EngineTester, at os prprios relatrios so
reconstruidos sem qualquer esforo.

Os algoritmos no determinsticos no inviabilizam o processo de repetio, dado que sempre


especificada uma semente. O gerador aleatrio utilizado no algoritmo dever produzir sempre a mesma
sequncia aleatria para a mesma semente. Caso seja encontrado um problema, as condies em que
este ocorreu podem sempre ser repetidas.

O EngineTester no fora os algoritmos a serem escritos numa linguagem prpria, nem numa linguagem
especfica, apenas determina que sejam programas de linha de comando e que aceitem uma linguagem de
comunicao de texto fixa, esta sim prpria, de forma a que o EngineTester possa criar um processo e
www.moodle.univ-ab.pt//print.php?id 51/85
26-01-2010 name
comunicar com o algoritmo. O EngineTester est implementado em Windows, pelo que os algoritmos
devem ser compilados para este sistema operativo.

A linguagem de comunicao pode ser utilizada de forma manual por um utilizador sem o EngineTester,
ao mandar correr o executvel correspondente ao algoritmo.

A linguagem de comunicao definida neste documento, sendo ainda fornecida uma implementao em
C++ de forma a que um programador apenas tenha de redefinir uma classe para implementar o
algoritmo, sem ter de se preocupar com a linguagem de comunicao. Assim, um algoritmo j
implementado pode ser facilmente adaptado para poder funcionar no EngineTester.

Algoritmos codificados em interpretadores que no possam criar executveis de linha de comando, como
o caso do VBA do Excel, no podem ser utilizados no EngineTester. Aconselha-se no caso do VBA
do Excel a fazer migrao para o Visual Basic.

No resto da seco est a descrio textual do laboratrio indicado nos vdeos, que pode ler em
alternativa ou em complemento aos vdeos.

6.1 Construo de um algoritmo


Descreve-se neste ponto a forma de construir um algoritmo de raiz com a respectiva linguagem de
comunicao, para funcionar com o EngineTester. A explicao feita tendo como base um exemplo
concreto para resoluo do problema "Partition", cuja implementao em C++ apresentada passo a
passo.

6.1.1 Algoritmo (Engine)


Considere-se numa primeira abordagem, um algoritmo um conjunto de instrues para resolver um dado
problema. Estas instrues actuam sobre os dados de entrada, produzindo em tempo finito os dados de
sada.

Os dados de entrada podem ser de dois tipos:

Dados do problema a resolver (instncia ou dados de teste, em ingls instance);


Afinaes do algoritmo (que so identificados como parmetros ou em ingls settings).

Os dados do problema so de natureza flexvel: assim um problema de rotas ter informao da rede de
estradas que se pode utilizar e um problema de afectao ter informao das entidades que se podem
afectar e respectivos custos. Por esse motivo os dados de um problema so guardados num ficheiro, num
formato prprio ao problema em questo e que o algoritmo dever conseguir ler.

Os parmetros so normalmente valores escalares, e em pequeno nmero. a parte do algoritmo em


que no h certeza do que melhor para todos os problemas. Nessas situaes, h que criar um
parmetro de entrada e definir um valor de omisso que funcione razoavelmente, mas com a
possibilidade de variando o valor do parmetro de entrada estudar qual a melhor opo e para que
casos.

De referir que podendo a instncia ser descrita por mais de um formato, poder um dos parmetros do
algoritmo ser a escolha do formato de leitura e/ou escrita da instncia.

Tambm os dados de sada podem ser de dois tipos:

www.moodle.univ-ab.pt//print.php?id 52/85
26-01-2010 name
A soluo do problema (que identificada como soluo ou em ingls solution)
Conjunto de indicadores sobre a soluo e a forma como esta foi obtida (que so identificados como
indicadores ou em ingls indicators)

O formato de dados da soluo tambm muito dependente do problema a resolver. A soluo pode
ser gravada em ficheiro. Os indicadores sero tipicamente valores escalares calculados com base na
soluo. Por exemplo, num problema de optimizao de rotas a soluo ser um trajecto, sendo um
indicador possvel o comprimento do trajecto.

Tal como no caso dos parmetros, pode-se definir o nmero de indicadores que se pretender. Existem j
alguns indicadores pr-definidos, nomeadamente:

tempo de execuo do algoritmo


nmero de estados analisados
nvel mximo atingido

O valor dos indicadores, tal como o valor utilizado dos parmetros do algoritmo, sero utilizados nas
anlises grficas. H que construir o maior nmero de indicadores possveis, uma vez que atravs deles
que se visualizar os resultados. Seria impossvel ver todas as solues, mas facilmente se pode ver uma
soluo que tenha um determinado indicador muito alto (ou baixo). Convm naturalmente que estes
indicadores sejam to independentes quanto possvel, de forma a apanharem aspectos diferentes da
soluo. A escala a que estes indicadores esto no relevante, uma vez que se pode construir
expresses com base nos indicadores e/ou parmetros, podendo alterar a escala destes.

Em teste de componentes de software, no caso do algoritmo bloquear, facilmente se identifica as


condies em que o erro ocorreu atravs dos parmetros de entrada em utilizao na altura. Podem-se
tambm criar indicadores, que cuja a funo seja verificar que a soluo vlida, por forma identificar
casos em que o algoritmo no funciona de acordo com as especificaes.

At agora centrmos a ateno em algoritmos para resoluo de problemas, mas podemos considerar
tambm algoritmos de outros tipos:

Algoritmos que transformam instncias de um problema em instncias equivalentes de outro problema


(interessante por exemplo em casos em que dispomos de um algoritmo para resoluo de problemas do
2tipo e no do 1)
Algoritmos que geram instncias de um problema (interessante para criar instncias de teste
automaticamente). Neste caso no h instncia de entrada.

Em resumo podemos ter algoritmos de trs tipos diferentes:

Algoritmos para resoluo de problemas


Algoritmos para transformao de instncias de um problema, em instncias equivalentes de outro
problema
Algoritmos de gerao de instncias

6.1.2 Linguagem de Comunicao


Um algoritmo (engine) um programa de linha de comando, que apenas comunica por texto. Esse texto
tem de seguir a linguagem de comunicao aqui definida. Caso programe em C++, no necessita de
implementar esta linguagem de comunicao, pode partir do cdigo j feito (ver seco seguinte), e
apenas tem de re-definir uma super-classe.

www.moodle.univ-ab.pt//print.php?id 53/85
26-01-2010 name
A prpria linguagem, no caso de no ser dado um comando vlido, envia uma descrio dos comandos,
como se pode ver na imagem seguinte.

Descrio detalhada dos comandos:

RUN - o algoritmo dever comear a correr neste momento, com os parmetros de entrada e
instncia que estiver carregada. Dever ser criado uma thread parte para correr o algoritmo, de modo a
que este consiga em simultneo ler comandos, nomeadamente o comando seguinte (STOP)
STOP - paragem forada do algoritmo. Ao receber este comando o algoritmo deve retornar o mais
breve possvel, com a melhor soluo caso j tenha encontrado alguma, caso contrrio sai sem soluo.
Como se poder ver na proposta de cdigo em C++, bastar incluir na condio de paragem dos ciclos
principais o mtodo Stop() para que esta funcionalidade seja implementada.
RESET - limpar todos os parmetros (ficam com valor de omisso), e descarregar a instncia que
eventualmente tenha sido carregada.
SET INSTANCE [instance data] - carregar um ficheiro (instncia), directamente pela entrada de
dados (acaba com um caracter final de ficheiro)
SET FILE [file name] - carregar um ficheiro (instncia), atravs do seu nome (com a directoria
completa).
SET SOLUTION [solution] - alterar a soluo corrente para a fornecida
SET [k] [value] - alterar o valor do parmetro [k] para o valor [value]
SET SEED [value] - alterar o valor da semente aleatria para o valor [value]
SET LIMIT STATES [states] - alterar o limite do nmero de estados permitidos para [states]
SET LIMIT TIME [miliseconds] - alterar o limite de tempo, em milissegundos para [miliseconds]

www.moodle.univ-ab.pt//print.php?id 54/85
26-01-2010 name
SET LIMIT LEVEL [maximal level] - alterar o limite do nmero mximo de nveis para [maximal level]
SET INFORMATION [value] - alterar o nvel de informao para [value]. O algoritmo que define
quantos nveis de informao tem. Quanto maior, mais detalhe o algoritmo reportar, sobre o seu
comportamento (ideal para saber o porqu de um resultado incorrecto).
GET INSTANCE - devolver a instncia para a consola
GET FILE [file name] - gravar a instncia para o ficheiro [file name]
GET SOLUTION - devolver a soluo actual
GET STATES - retornar o nmero de estados analisado
GET TIME - retornar o tempo utilizado em milissegundos
GET LEVEL - retornar o nvel mximo atingido
GET SETTINGS - retornar o nmero de parmetros que o algoritmo tem
GET [k] - retornar o valor actual do parmetro [k]
GET NAME [k] - retornar o nome do parmetro [k]
GET DESCRIPTION [k] - retornar uma descrio do parmetro [k]
GET MINIMAL [k] - retornar o valor mnimo possvel para o parmetro [k]
MAXIMAL [k] - retornar o valor mximo possvel para o parmetro [k]
GET INDICATORS - retornar o nmero de indicadores disponvel
GET INDICATOR [k] - retornar o valor do indicador [k]
GET INDICATOR NAME [k] - retornar o nome do indicador [k]
GET INDICATOR DESCRIPTION [k] - retornar uma descrio do indicador [k]
GET ENGINE NAME - retornar o nome do algoritmo (engine)
GET ENGINE VERSION - retornar a verso do algoritmo
GET ENGINE DATE - retornar a data de compilao do executvel
GET ENGINE AUTHOR - retornar o nome do autor (ou autores)
GET ENGINE CONTACT - retornar um ou mais contactos com o autor
GET ENGINE DESCRIPTION - retornar uma descrio curta do algoritmo
GET LIMIT STATES - retornar o nmero de estados permitidos
GET LIMIT TIME - retornar o tempo em milissegundos permitido
GET LIMIT LEVEL - retornar o nvel mximo permitido
GET INFORMATION - retornar o nvel de informao actual
INFORMATION [value] - retornar uma descrio sobre o nvel de informao [value]. O primeiro
nvel de informao no dever mostrar nada.

6.1.3 Implementao C++


A instalao do EngineTester cria uma directoria "Source Code\NewEngine" com o cdigo necessrio
para comear a implementar o algoritmo sem ter de se preocupar com a linguagem de comunicao.

A directoria "NewEngine" tem os seguintes ficheiros que podem ser consultados, mas no devem ser
alterados:

TEngine.cpp e TEngine.h que correspondem respectivamente implementao e declarao da super-


classe TEngine. Todos os algoritmos devem ser uma subclasse desta classe, que contm todos os
mtodos que os algoritmos podem e devem redefinir.
TRand.cpp e TRand.h com a implementao e declarao de uma classe auxiliar geradora de nmeros
aleatrios
TVector.h com a implementao e declarao de uma classe auxiliar de vectores dinmicos

So tambm criados os ficheiros que vo ser alterados para conter a implementao do novo algoritmo:

NewEngine.cpp o ficheiro tem a funo main, e o cdigo da linguagem de comunicao. Aqui h que
www.moodle.univ-ab.pt//print.php?id 55/85
26-01-2010 name
modificar apenas o nome da subclasse com o novo algoritmo
TNewEngine.cpp TNewEngine.h com a implementao e declarao do novo algoritmo numa
subclasse de TEngine

Para iniciar um novo algoritmo tem que alterar o nome "NewEngine" pelo nome do seu algoritmo, tanto
no nome dos ficheiros como tambm nas referncias internas dentro dos ficheiros "NewEngine.cpp",
"TNewEngine.cpp" e "TNewEngine.h". De seguida basta implementar o algoritmo editando apenas os
novos ficheiros "TNewEngine.cpp" e "TNewEngine.h".

Para compilar este cdigo o compilador tem de ser posto em modo de multi-thread. O presente cdigo
foi testado no Visual Studio 6.0, e de omisso no est neste modo. Se tem dvidas que o seu
compilador tenha um modo multi-thread, compile os ficheiros antes de os alterar, para ver se consegue.
Caso no consiga compilar, o problema ser na chamada a "_beginthread" e "_endthread". Notar que
uma thread diferente de um processo. Esta implementao necessita de uma thread para a leitura de
dados, e cria outra thread para o algoritmo correr. No caso do Visual Studio 2005, no preciso fazer
nada. Na figura est o resultado aps construir um projecto "Win32 Console Application", adicionar os
ficheiros e substituir o "NewEngine" por "Partition". Est pronto a correr.

Pode fazer uma verso que no suporte multi-thread substituindo o _beginthread pela chamada prpria
funo e comentando o _endthread, mas tal pode ter efeitos indesejveis. O EngineTester assume que a
comunicao entre a aplicao EngineTester e todos os algoritmos (engines) abertos, deve estar sempre
activa, e no haver momentos em que a comunicao ignorada porque est um algoritmo a correr.

Aps a compilao correcta tem um conjunto de tarefas a fazer nos ficheiros TNewEngine.cpp e
TNewEngine.h:

identificar o algoritmo alterando os nomes no mtodo Engine


criar a estrutura de dados para guardar uma instncia em TNewEngine

www.moodle.univ-ab.pt//print.php?id 56/85
26-01-2010 name
criar a estrutura de dados para guardar uma soluo
verificar que construtor e destrutor esto de acordo com a estrutura criada
implementar Load/Save da instncia
implementar LoadSolution/SaveSolution
implementar em Reset: identificao de todos os parmetros (ver cdigo comentado); identificao de
todos os indicadores (ver cdigo comentado); adicionar modos de informao, adicionando valores para
info_description (ver declarao de TEngine).
implementar em Run o algoritmo, e adicionar parmetros se necessrio (nesta fase j se pode utilizar o
EngineTester para testes). Nos ciclos mais importantes, incluir no critrio de paragem a chamada ao
mtodo Stop() (de TEngine), para que seja possvel parar o algoritmo no caso do utilizador ter mandado
parar, ou o tempo estar esgotado (ou qualquer outro critrio de paragem). H que actualizar tambm o
nmero de estados e nvel mais alto (value_states, value_level de TEngine). Por exemplo, o loop base de
um algoritmo pode ser: while(!Stop()) { value_states++; /*processar*/ }
implementar indicadores (mtodo Indicator)
optimizaes, testes de fiabilidade

tudo. O algoritmo est pronto a ser testado no EngineTester.

6.1.4 Exemplo (partition)

A partir dos ficheiros da directoria "NewEngine", criar um algoritmo para o problema da partio
(partition). Este problema consiste em tendo um conjunto de nmeros inteiros, saber se se podem dividir
em dois grupos cuja soma seja exactamente igual. O algoritmo a implementar determinstico e
exaustivo, percorre todas as parties possveis (algumas indirectamente) e retorna assim que encontrar
uma vivel.

Fazer os seguintes passos:

criar um projecto do tipo "Console Aplication" utilizando o ambiente de desenvolvimento desejado, e


selecionar "empty project" (Visual Studio 2005: projecto de C/C++; template "Win32 Console
Application"; nas application settings escolher "console application" como tipo e "empty project" como
opes adicionais).
copiar todos os ficheiros da directoria de "NewEngine" para a nova directoria e alterar o nomes de
"NewEngine" para "Partition"
incluir os ficheiros no projecto e editar Partition.cpp/TPartition.cpp/TPartition.h e fazer substituio
automtica de "NewEngine" por "Partition"
alterar configurao do projecto (no Visual Studio 6.0: Project|Settings|C/C++|Code
Generation|Multithreaded (ou Debug Multithreaded)). No Visual Studio 2005 no necessrio fazer
nada.
actualizar o mtodo Engine de TPartition e mandar compilar. Se houver problemas, ler a seco
anterior, caso contrrio correr e escrever na consola "get engine name", ver o resultado e fechar a
consola.
o prximo passo criar a estrutura de dados para guardar a instncia. Como um vector de nmeros
inteiros, e j existe um objecto auxiliar para vectores, TVector, criar uma varivel deste tipo, com
elementos inteiros (int), em TPartition: TVector<int> instance;
a soluo poderia ser outro vector de inteiros (ou um vector binrio), para guardar os nmeros de uma
das divises. Como o problema apenas de saber se h ou no uma soluo, e no de encontrar uma
soluo caso exista, no vamos guardar a soluo.
o construtor e destrutor esto ok, no preciso de nada porque foi criado apenas um objecto que se
destroi ele prprio automaticamente, no deixando lixo
implementar o mtodo Load/Save: no mtodo Reset adicionar a linha instance.Count(0); ||| aproveitar
www.moodle.univ-ab.pt//print.php?id 57/85
26-01-2010 name
o cdigo feito no mtodo Load e na linha para processar a string inserir o comando
instance.Add(atoi(str)); (neste caso dever existir um nmero em cada linha) e o comando
if(instance.Last()==0) break; (para acabar de ler a instncia assim que venha um zero) ||| no mtodo save
colocar um ciclo a percorrer todos os elementos, em vez da chamada ao fprintf actual: for(int
k=0;k<instance.Count();k++) fprintf(f,"%d\n",instance[k]); ||| compilar e correr e escrever: "set instance"
e de seguida digitar nmeros (um por linha) e acabar com um 0 (zero), escrevendo o comando "get
instance". O engine dever escrever a instncia que acabou de carregar.

deixar a implementao LoadSolution/SaveSolution por fazer


no mtodo Reset, no colocar nenhum parmetro, e colocar apenas um indicador (alterar cdigo: em
indname "Resultado"; em inddesc "0 - no possvel; 1 - possvel.")
criar uma varivel inteira resultado em TPartition: int resultado; no mtodo Reset inicializar a zero:
resultado=0;
no mtodo Indicator, no caso do "indicator 1" em vez do return 0; colocar return resultado;

www.moodle.univ-ab.pt//print.php?id 58/85
26-01-2010 name

Falta agora implementar o algoritmo. Primeiro h que salientar alguns pontos que nos permitem aliviar
algum tempo de processamento:

o algoritmo apenas deve tentar encontrar parties caso a soma total dos nmeros seja par. Caso a
soma seja impar impossvel obter uma partio uma vez que os nmeros so todos inteiros, e nessa
situao o engine pode retornar logo impossvel
processar os elementos 1 a 1, e ter sempre o valor da soma total a dividir por dois (para no
considerar parties com valores superiores a esse valor)
ter o valor do somatrio dos elementos na partio a considerar
considerar em cada passo um elemento i: se somando o valor de i com os elementos j na partio for
igual ao total/2, retornar sucesso; caso seja superior, tentar fazer parties apartir de i+1 sem entrar com
i; caso seja inferior, se no houver mais elementos (i o ltimo), retornar insucesso, caso contrrio tentar
apartir de i+1 entrando em linha de conta com i, e caso no d tentar sem entrar com i.

Se for suficiente a ideia, ou se conseguir implementar um algoritmo seu, fora. Caso contrrio pode fazer
os seguintes passos, ao estilo de laboratrio:

criar mtodo partition com os argumentos o valor i, subtotal e total2, retornando inteiro
no mtodo Run, calcular a soma total
caso seja divisivel por 2, chamar partition, caso contrrio 0, e guardar o resultado na varivel resultado

www.moodle.univ-ab.pt//print.php?id 59/85
26-01-2010 name

no mtodo partition, verificar se subtotal com i fica igual a total2, retornar sucesso nesse caso.
verificar se i==0, nesse caso no h hiptese, retornar insucesso
verificar se sem este elemento existe uma partio, e retornar sucesso se existir
verificar se o valor no ultrapassado se se contar com este elemento, e retornar a chamada
partio
na ltima linha inserir return 0; porque nesse caso no possvel

Est feito, agora h que fazer um pequeno teste antes de o testar no EngineTester. Compilar e correr,
inserir uma instncia divisivel e outra divisivel e mand-lo correr.
www.moodle.univ-ab.pt//print.php?id 60/85
26-01-2010 name

Utilizar os seguintes comandos (no engine):

set instance - e inserir a instncia como anteriormente


run - e esperar que aparea "Run end."
get indicator 1 - e ver o resultado

Repetir os comandos escrevendo uma instncia que tenha o resultado oposto.

Estes pequenos testes no garantem no entanto que o algoritmo esteja a funcionar correctamente, nem
do ideia da sua complexidade algoritmica. So necessrios testes mais extensos, algo que o
EngineTester facilita e sem este provavelmente o investigador j fatigado nesta altura, acabaria por dar o
trabalho como concluido. Neste caso a complexidade algoritmica possvel de calcular, de O(2^n)
para o pior caso, mas mesmo neste problema no h ideia do tempo mdio para um conjunto por
exemplo de 1000 inteiros gerados aleatoriamente entre 1 e 1000.

6.2 Utilizao do Engine Tester


Um documento no EngineTester guarda informao necessria para executar um conjunto de testes,
podendo envolver mais do que um algoritmo, mais do que um conjunto de parmetros para cada
algoritmo, e mais que um conjunto de instncias, tendo tambm a informao sobre a construo de
grficos de resultados. Este texto assume que se leu a seco anterior, e se tem conhecimento do que
um engine (algoritmo).

6.2.1 Dialog Base (Main View)


Ao iniciar o EngineTester, um novo documento criado, sendo aberta a dialog base deste. Esta dialog
permite visualizar e editar os elementos de quatro conjuntos, os quais constituem o documento
EngineTester. Esses conjuntos so: conjunto de instncias (instance sets); conjunto de parmetros (setting
sets); conjunto de algoritmos (engines); conjuntos de grficos (result views).

Cada conjunto tem uma "combobox", em que est seleccionado o elemento desse conjunto activo, e
possui os botes Add/Delete para adicionar e remover um elemento a cada conjunto respectivamente. O
nome do elemento e respectivas configuraes, so editveis em dialogs especficas.

www.moodle.univ-ab.pt//print.php?id 61/85
26-01-2010 name

O boto "?" junto de cada conjunto, tal como outros botes com "?" espalhados um pouco por todo o
lado, d uma informao breve do que representa.

Para abrir uma dialog de edio de um dos elementos dos quatro conjuntos, basta que seleccione o
elemento. Faa isso para as instncias, e de seguida minimize a dialog base.

6.2.2 Conjunto de Instncias (instance sets)


Um conjunto de instncias definido pelo seu nome, e um conjunto de ficheiros, em que cada ficheiro
tem os dados de uma instncia.

Alternativamente a se dar os ficheiros, pode-se fornecer um engine que gera as instncias, sendo nesse
caso passado o resultado desse engine para o engine que necessitar deste conjunto de instncias.

www.moodle.univ-ab.pt//print.php?id 62/85
26-01-2010 name

Vamos continuar com o exemplo dado, Partition. H que construir um conjunto de instncias de teste
para o partition. O formato simples, um conjunto de nmeros acabando no 0, com os nmeros postos
um por linha:

escreva o nome do conjunto de testes (por ex: "partition set")


adicione um ficheiro, e crie uma directoria "instances" debaixo da directoria do Partition criado na
seco anterior, e d um nome ao ficheiro
como o ficheiro no existe, este criado. Para o editar no notepad, apartir do EngineTester, pode
fazer um duplo click sobre a linha do ficheiro. Edite e inicialize com valores que queira.
repita o processo at existirem uma dzia de ficheiros de instncias

conveniente que todo o conjunto esteja na mesma directoria. No caso de se levar todo o teste para
outro computador, incluindo as instncias, as directorias podem ser diferentes, e nesse caso o
EngineTester pergunta a nova directoria. Para as restantes instncias no conjunto, assume que a
directoria trocada se mantm, mas se no achar o ficheiro pergunta por nova directoria. De forma a
poupar trabalho de indicar novas directorias, aconselha-se a que um conjunto de instncias esteja na
mesma directoria.

Ao seleccionar um ficheiro na lista, na zona direita o ficheiro mostrado. Se no cober na zona


completamente, pode navegar no ficheiro atravs de arrastar o rato, e atravs de um duplo-click
acabando em arrastar o rato.

www.moodle.univ-ab.pt//print.php?id 63/85
26-01-2010 name

Na imagem anterior pode-se ver o ficheiro i05.txt seleccionado, sendo o seu conteudo mostrado na zona
da direita.

Convem que as instncias de teste sejam diferentes, de forma a poder ver como o algoritmo se comporta
nas diferentes situaes. No Partition, pode-se suspeitar ser relevante ao desempenho do algoritmo o
nmero de elementos, e o nmero de dgitos mdio por elemento. Naturalmente que as instncias cuja
soma dos elementos no seja par, de pouco interesse, j que o algoritmo detecta que impossvel e
rejeita de imediacto.

O leitor facilmente concordar que um conjunto construido manualmente dificilmente pode ter instncias
de acordo com o ideal especificado no pargrafo anterior. Primeiro devido a ser trabalhoso construir
instncias grandes, e segundo porque para tirar concluses so necessrias muitas instncias, e no
apenas uma dzia.

Apesar destas questes, vamos para j manter o exemplo assim, de forma a este ficar simples, e passar
configurao do nosso engine.

6.2.3 Conjunto de algoritmos (Engines)

Seleccione na toolbar direita, o icon que se parece com um motor. Esta um forma rpida de trocar de
dialog, passando a editar o engine de seleccionado na dialog base.

www.moodle.univ-ab.pt//print.php?id 64/85
26-01-2010 name

Para configurar um engine, h que seleccionar o executavel de linha de comando que implementa o
algoritmo. Carregue no boto "Browse" e seleccione o executvel Partition.exe construido na seco
anterior. Na zona "Engine executable" dever aparecer o executvel. Se necessrio, pode criar mais que
um engine com o mesmo executvel, desde que d nomes diferentes a cada engine no documento
EngineTester.

Para alm do nome, um engine no EngineTester tem:

um subconjunto dos conjuntos de instncias definidos


um subconjunto dos conjuntos de parmetros definidos
um conjunto de variveis de saida
um subconjunto dos indicadores do motor (que se podem utilizar nas variveis de sada)
um formato de construo do nome dos ficheiros processados, no caso de se querer gravar aps
transformar uma instncia

A lista do canto superior-direito, tem as instncias que possui juntamente com o nmero de ficheiros. A
lista permite multipla-seleco, de forma a que se seleccione os conjuntos de instncias a enviar para este
engine. A lista de conjuntos de parmetros, no canto inferior-direito, segue a mesma filosofia.

O campo dos indicadores permite seleccionar um subconjunto dos indicadores possveis. Apenas os
seleccionados aqui sero pedidos ao engine, aps o fim do processamento, e estaro disponveis para
construo das variveis de sada. Desta forma, caso o engine tenha por exemplo 20 indicadores, e
apenas sejam precisos 3, evita-se ter de calcular 20 indicadores para apenas utilizar 3.

O formato do campo dos indicadores o seguinte:

[ind]:=[ind1]|[ind1] [ind]
[ind1]:==[nmero]|[nmero]-[nmero]|[nmero]-[nmero]:[nmero]

Um ou mais [ind1] podem ser inseridos, desde que separados por um espao. Um [ind1] ou um
www.moodle.univ-ab.pt//print.php?id 65/85
26-01-2010 name
nmero, ou do tipo [a]-[b] e nesse caso so todos os nmeros entre [a] e [b] inclusiv, ou ento do
tipo [a]-[b]:[c], e nesse caso so todos os nmeros de [a] a [b] de [c] em [c]. Por exemplo: "1 6-9 20-
80:15" corresponde aos nmeros 1 6 7 8 9 20 35 50 65 80. Como apenas temos um s indicador,
implementado no Partition, deixa-se este campo com o valor de omisso "1".

As variveis de sada podem ser construdas utilizando as funes matemticas comuns (sin, cos, sqrt,
pow,...) e com base em diversas variveis:

I[i] - valor do indicador [i] seleccionado (1 o primeiro)


VS, VT, VL - valor utilizado de nmero de estados, tempo e nvel mximo
PS, PT, PL - valor dos parmetros de limites do nmero de estados, tempo e nvel mximo
P[i] - valor do parmetro na ordem [i] do conjunto de parmetros
NE, NI, NS - nmero do engine, do conjunto de instncias e do conjunto dos parmetros

Como temos apenas um indicador, para j podemos colocar as seguintes variveis: VT; I1; NI. Ateno
que para adicionar uma nova varivel, a lista de variveis no pode estar seleccionada, caso contrrio
editada a varivel seleccionada e no criada nova varivel.

No campo de formatao de ficheiros (File format), coloca-se o formato do nome dos ficheiros para
serem gravados com novo nome, aps serem processados. Caso o campo esteja em branco, os ficheiros
no so gravados:

prefixo*prefixo_apagado*sufixo_apagado*sufixo
utilizar #i, #s, #e, para substituir pelo nmero da instncia, nmero do parmetro, e nmero do engine
respectivamente

Os ficheiros criados para teste ficaram com os nomes: "i01.txt"; ...; "i12.txt". Para os modificar de forma
a ficarem "partition01.txt"; ... ;"partition12.txt", bastaria inserir a formatao: "partition*i**", ou seja,
apagar o i e adicionar o prefixo "partition".

Se um ou mais ficheiros tiverem sido apagados, o nmero do ficheiro deixa de ter significado. Nesse caso
pode-se ignorar o nmero: "partition#i.txt". Esta formatao ignora o nome original da instncia, e
distingue as instncias apenas no nmero de instncia.

6.2.4 Conjunto de parmetros (Setting Sets)


O conjunto de parmetros tem de ser identificado por um nome, e os valores dos parmetros colocam-
se da mesma forma que os indicadores na dialog de Engine.

Cada engine pode ter um conjunto de parmetros, para adicionar novo parmetro basta escrever o
nmero do parmetro e os valores, e nova linha adicionada. Os parmetros do algoritmo que no
ficarem especificados, ficam com o valor de omisso. No nosso exemplo do Partition, no temos de
momento nenhum parmetro.

Quatro parmetros so fixos: semente do gerador aleatrio (Seed Value), de forma a que em algoritmos
no determinsticos o resultado possa ser repetido; nmero mximo de estados analisados (States Limit);
tempo mximo em milisegundos (Time Limit), mas apenas nesse instante ser enviada ordem para sada,
e no caso do algoritmo no chamar com frequncia o mtodo Stop (ver seco anterior), este pode
ultrapassar este valor; nvel mximo a explorar (Level Limit), sendo o nvel um conceito mais aplicvel a
algoritmos de procura em rvore, mas pode ser livremente utilizado. Voltaremos com um exemplo a esta
dialog, quando se adicionar parmetros ao Partition.

www.moodle.univ-ab.pt//print.php?id 66/85
26-01-2010 name

O nmero de elementos deste conjunto pode crescer rapidamente. Suponhamos que temos 4
parmetros, e que em cada um queremos testar 10 valores diferentes. Est-se nesta situao a definir
10^4 hipteses, que so 10.000 corridas. Este valor conjugado com o nmero de instncias, por
exemplo 100, daria um total de 1.000.000 de corridas.

Aconselha-se a fazer testes pequenos primeiro, antes dos grandes testes. Nos testes pequenos detecta-
se rapidamente pequenos problemas com o algoritmo, ou com os resultados, que podem eventualmente
levar escolha de outros parmetros para o grande teste.

6.2.5 Grficos de Resultados (Result Views)


Os grficos de resultados inicialmente no tm elementos. Devem ser construdos no final, uma vez que
so dependentes dos objectos inseridos nos restantes conjuntos.

Antes de criar um grfico, mande o algoritmo correr, atravs do menu Tester|Start ou do boto "Start".
Ir abrir uma outra janela que ir comunicar com o engine. Esta janela tambm abriria no caso de na
dialog Engine carregar no boto "Open".

www.moodle.univ-ab.pt//print.php?id 67/85
26-01-2010 name

A janela apresenta informao do engine no canto inferior-esquerdo, permite enviar qualquer comando
no canto superior-esquerdo. No resto da zona esquerda tem uma "combobox" com os nveis de
informao possveis, outra "combobox" com os parmetros possveis e respectivo valor, uma terceira
"combobox" com os indicadores. Seleccione o valor "Resultado" nos indicadores, e ver informao
descriptiva, que voc prprio escreveu quando o construiu. De resto esto os limites do nmero de
estados, tempo em milisegundos e nvel mximo.

Caso no esteja um teste a correr, pode utilizar esta dialog para comunicar com um engine, para saber
que parmetros e indicadores tem implementados, ou para seleccionar uma determinada instncia que d
um resultado incompreensvel, seleccionando um nvel de informao adequado para se compreender o
porqu do resultado.

J tendo corrido, faa Tester|Export|Results e grave num ficheiro. Veja o resultado. Dever ter 12 linhas,
caso no tenha abra a dialog Engine e seleccione o conjunto de instncias. A informao aparece em
forma tabelar, com o nmero de Engine, nmero de instncia e nmero de parmetro (neste caso no h
parmetros), seguidos das variveis de sada (VT, I1, NI).

Crie agora uma vista grfica atravs da dialog base, e responda "no" a todas as perguntas. Essas
perguntas so relativas a cada elemento escolhido (do conjunto dos engines, das instncias e dos
parmetros), de forma a fazer um grfico entrando em linha de conta apenas com resultados desse
elemento. Abra agora a vista grfica criada.

www.moodle.univ-ab.pt//print.php?id 68/85
26-01-2010 name

O grfico partida mostra os valores seleccionados em srie. Tendo 3 variveis de sada, ficamos com 3
sries com tantos elementos quantas as corridas, neste caso 12. Mesmo neste grfico podemos ver que a
instncia 10 houve um tempo muito elevado de 350 milisegundos.

Dado que a escala igual para todas as sries, a segunda srie com o resultado 0 ou 1 no se v. Pode-
se portanto dividir o tempo por 1000 para passar a segundos, e o nmero da instncia por 10 (na dialog
Engine). Antes de mandar correr novamente (pode-se manter a vista grfica sempre aberta), carregue no
boto "Clear results", caso contrrio os resultados so adicionados aos anteriores.

Neste caso, abrindo a dialog do conjunto de instncias, foi possvel ver a instncia que estava a consumir
mais tempo, e esta tinha 43 elementos.

A vista grfica, para alm de sries, pode visualizar basicamente histogramas e scatterplots. Com o menu
de contexto do DataView, possvel editar a vista grfica, sendo essas modificaes gravadas no
documento EngineTester. Vamos mostrar algumas dessas funcionalidades com o evoluir da anlise ao
nosso algoritmo Partition.

6.2.6 Anlise ao Partition


Dos primeiros testes ficou a suspeita de que o tempo de computao depende do nmero de elementos.
Como verificar isso? Primeiro h que construir um indicador no engine que retorne quantos elementos a
instncia tem. Desta forma podemos utilizar esta informao para cruz-la com o tempo de computao.

Abra o projecto do Partition e no mtodo Reset adicione um novo indicador "N" com descrio
"Nmero de elementos da instncia.". No mtodo Indicator, crie um novo "case" para o indicador e
retorne o nmero de elementos de instance: case 1: return instance.Count(); break;

Compile, mas antes feche o EngineTester gravando o ficheiro, uma vez que pode ter o executvel aberto,
e volte a abrir o EngineTester novamente aps ter o ficheiro compilado.

www.moodle.univ-ab.pt//print.php?id 69/85
26-01-2010 name
Para verificar que o novo indicador est funcional, abra a dialog de engine, e carregue no boto "Open".
Ir abrir a dialog de comunicao com o engine e um processo onde estar o executvel a correr. Se
quiser pode abrir o Task Manager e ver o novo processo. Seleccione o valor "N" na "combobox" com
os indicadores para ver a sua descrio.

Na dialog de Engine, coloque tambm o indicador 2, ficando portanto "1 2". Nas variveis de sada
coloque o indicador I2, de forma a ter-se acesso a este valor nas anlises. Mande correr e reparar que
no h nada de novo na vista grfica. Abra a dialog base, e apague a vista grfica refazendo-a novamente
da mesma forma, j que adicionou uma varivel de sada. Ver agora a nova varivel.

www.moodle.univ-ab.pt//print.php?id 70/85
26-01-2010 name

Agora h que construir um gerador. Comece por criar um engine apartir de NewEngine, tal como foi
feito para criar Partition, e d o nome de GenPartition. Como a estrutura de dados ser igual do
Partition, crie tambm a varivel instance.

O gerador precisa de um gerador de nmeros aleatrio. fornecido a classe TRand para gerar valores,
no sendo necessrio instanciar a classe j que os seus membros so estticos. A semente logo
inicializada no TEngine, pelo que no h que preocupar com o assunto, apenas chamar o mtodo Seed();
no incio do mtodo Run, e chamar o mtodo TRand::rand() sempre que for preciso um novo valor
aleatrio.

O gerador necessita de parmetros de entrada, como o nmero de elementos a gerar (N). Cada nmero
pode ser gerado de acordo com uma distribuio uniforme, de 1 a M, mas obviamente h instncias que
podem ter os nmeros distribuidos no uniformemente mas sim de forma logaritmica ou outra situao.
Abstraindo desse facto, pode-se ento criar um parmetro (M) com o maior nmero possvel.

Crie os dois parmetros acima, com valores de omisso razoveis (10 e 1000 respectivamente). No
mtodo Run faa a gerao dos valores: Reset(); for(long k=0;k<value[0];k++)
instance.Add(TRand::rand()%value[1]+1); instance.Add(0);

Compile e corra para efectuar o primeiro teste: no engine, faa "run" e "get instance" para ver a instncia
gerada. Altere o valor dos settings para verificar que os parmetros influnciam a instncia gerada. Se
alterar o valor do Seed antes de mandar correr, verifica que a mesma instncia gerada.

Aparentemente tudo em condies para testar o desempenho do algoritmo Partition, mas na verdade no
possvel verificar o resultado sucesso/insucesso, devido a no haver essa informao.

Em todos os problemas, em todas as dimenses, h normalmente instncias simples. De igual forma,


neste caso, muitas vezes as instncias geradas impossveis no somam um valor par e o Partition
retornar logo, ou uma instncia impossvel pode ter um nmero muito mais elevado que os restantes

www.moodle.univ-ab.pt//print.php?id 71/85
26-01-2010 name
tornando a instncia mais simples de resolver. As instncias simples inviesam a anlise de desempenho
nas instncias dificeis.

Para evitar gerar instncias demasiado simples, resolveu-se gerar instncias sempre possveis, porque
aparentemente no haver muitas destas instncias demasiado simples, a no ser que um s nmero seja
igual soma dos restantes. Por isso a soluo dever ter uma seleco de aproximadamente metade dos
elementos de forma a que a complexidade seja mxima.

Resta saber como transformar o gerador puro anterior num gerador que garanta que existe uma soluo?
Normalmente bastar construir uma soluo. Neste caso basta ter dois registos de somatrios parciais, a
cada nmero que gerado somado num dos registos (o que tiver valor inferior), sendo o ltimo nmero
a diferena de valor entre os dois registos. Assim garante-se que h uma diviso, mas para que o
algoritmo que resolver no possa fazer uso do algoritmo de gerao para resolver o problema, h que
baralhar (ou ordenar) a ordem dos nmeros gerados antes de devolver a instncia
(instance.RandomOrder();).

Caso no consiga implementar, siga os seguintes passos, no mtodo Run:

linha inicial: long soma1=0,soma2=0;


substituir ciclo: for(long k=0;k<value[0]-1;k++) { instance.Add(TRand::rand()%value[1]+1);
if(soma1<soma2) soma1+=instance.Last(); else soma2+=instance.Last(); }
depois do ciclo: if(soma1<soma2) instance.Add(soma2-soma1); if(soma2<soma1)
instance.Add(soma1-soma2);
baralhar: instance.RandomOrder();
no esquecer de adicionar 0 no fim: instance.Add(0);

Compile e corra, fazendo novamente os mesmos testes. O gerador est pronto para ser utilizado.

Volte a abrir no EngineTester o mesmo documento, e adicione um novo engine (o GenPartition). O


gerador necessita de valores para N e M, e necessrio dizer quantas instncias se quer. Para fazer esta
configurao tem que se criar um conjunto de parmetros (setting sets).

Edite o conjunto de parmetros criado de omisso (ou crie um novo), e d o nome de "GenPartition".
Para o valor do primeiro parmetro (N) colocar "10-100:10", e para o segundo parmetro colocar "10
100 1000". De forma a ter mais do que uma instncia para um conjunto de parmetros, colocar na
semente (Seed Value) 5 valores "1-5".

www.moodle.univ-ab.pt//print.php?id 72/85
26-01-2010 name

Abra agora o engine GenPartition e seleccione o conjunto de parmetros criado. Coloque no formato
para gravao a string "g#s.txt" de forma a gravar as instncias.

Mande correr, e os ficheiros devem ficar gravados. Mova os ficheiros criados para a directoria de
instncias do Partition e crie agora um novo conjunto de instncias, e adicione os ficheiros gravados para

www.moodle.univ-ab.pt//print.php?id 73/85
26-01-2010 name
os ver.

Notar que se utilizou o TRand::rand() para gerar nmeros aleatrios, a instncia g100.txt visualizada na
imagem anterior, dever coincidir com a sua, dado que a semente utilizada na sequncia aleatria ter
sido a mesma. Verifique em qualquer das formas se tem uma chamada no mtodo Run() ao mtodo
Reset(), e no caso positivo apague-a, caso contrrio os valores dos settings alterados so ignorados e
substituidos pelos valores de omisso. Pode confirmar que est tudo em condies relativamente
instncia g0.txt que deve ter os valores: 5 6 8 9 9 1 1 5 9 1 0.

Pode agora facilmente repetir os testes do Partition utilizando apenas as instncias geradas, bastando
para isso trocar a seleco do conjunto de instncia a utilizar, na dialog de Engine do Partition. Nesse
caso, no interessa o resultado do gerador, pelo que h que limpar as variveis de sada, de forma a que
este no corra. Antes de mandar correr, abra a vista grfica e limpe os resultados entretanto
armazenados, de forma a ir vendo os resultados a sarem medida que so processados.

Enquanto corre, pode abrir o Task Manager para ver a ocupao do CPU, e ir monitorizando os
resultados. Haver 4 variveis, a primeira o tempo, a segunda o resultado (que dever ser sempre 1,
devido a que todas as instncias so possveis), a terceira o nmero de instncia e a quarta o nmero de
elementos.

Ser interessante ver o tempo vs tamanho, de forma a verificar se h dependncia. Para isso h que
primeiramente apagar do relatrio as variveis que no se querem (a 1 e 2, ficando a 0 e 4). As variveis
continuam disponveis para outros relatrios. Boto da direita, seguido de Edit/Delete/Columns... e
escrever "1 2". Apartir desse momento apenas se v informao de duas variveis.

Agora h que passar a vista para tipo Scatterplot: boto da direita, seguido de Settings/Type/Scatterplot.
Falta agora dar nomes certos, atravs tambm do boto da direita, seguido de Edit/Labels/Axis e
Edit/Labels/Caption. Estas alteraes ficam guardadas no documento.

www.moodle.univ-ab.pt//print.php?id 74/85
26-01-2010 name

Verifica-se que o algoritmo, nas instncias de 60 elementos j leva muito tempo. Como o nosso engine
no tem verificaes para abortar o algoritmo, este no pra seno quando acabar, retornando sucesso
ou insucesso.

Na nossa implementao, no mtodo "partition" h que actualizar o nmero de estados analisados,


adicionando logo na primeira linha o comando: value_states++; e no mesmo mtodo, antes da primeira
chamada recursiva, executar o comando: if(Stop()) return 0;. Desta forma o algoritmo retornar assim
que um dos critrios de paragem forem atingidos, com o valor de insucesso.

Aps compilar, volte a abrir o EngineTester no mesmo documento, e crie um novo conjunto de
parmetros Partition, e coloque no limite de tempo 10000 milisegundos, e no nmero de estados
100000000. Se o nmero de estados permitido for inferior, provvel que o algoritmo pre no devido
ao limite de tempo mas sim ao limite de estados. Corra novamente, mas antes no se esquea de no
Engine Partition seleccionar o respectivo conjunto de parmetros, e limpar os resultados anteriores.

www.moodle.univ-ab.pt//print.php?id 75/85
26-01-2010 name

Se correr de imediacto, ver que o limite de tempo ignorado, acabando todas as instncias
practicamente instantaneamente. Tal deve-se ao facto de no mtodo "Load" haver uma chamada ao
mtodo "Reset", sendo nesse mtodo reposto o tempo limite de omisso (1 segundo) e limite de nmero
de estados (1000 o que pouco neste caso). H que trocar a chamada a "Reset" no mtodo "Load"
pelos comandos: instance.Count(0); resultado=0;

www.moodle.univ-ab.pt//print.php?id 76/85
26-01-2010 name
Correndo em outro computador, o grfico ser idntico, apenas os pontos podem ser ligeiramente
deslocados para a esquerda ou direita, conforme o computador mais rpido ou mais lento, mas devido
s caractersticas exponenciais do algoritmo, estas diferenas no fariam grande diferena. Caso o limite
seja o nmero de estados, no teria havido diferena nenhuma.

Pode-se observar facilmente pelo grfico, que de 30 elementos a 60 elementos as instncias vo de


todas simples a todas complexas, ao ponto de nenhuma instncia ser resolvida dentro do tempo limite.
Aps esta anlise, h que ento fazer outra anlise mais fina, de 30 a 60 elementos, e portanto ter que
repetir o process.

O EngineTester permite no entanto aliviar este processo, no sendo necessrio que as instncias sejam
gravadas. sempre conveniente gravar e ver as instncias quando se est a desenvolver o gerador, mas
aps ter a certeza que este funciona bem, pode-se utiliz-lo apenas para gerar instncias de determinado
tipo, sendo as instncias utilizadas directamente no gerador.

Edite o conjunto de parmetros GenPartition, e altere os valores do parmetro 1 para "30-60:2". No


engine GenPartion, apague o formato de escrita para no gravar ficheiros, e crie um conjunto de
instncias seleccionando este gerador.

No engine Partition, seleccione o novo conjunto de instncias GenPartition2, limpe os resultados e mande
correr. Os resultados so refeitos automaticamente. A vista grfica volta a dar informaes preciosas
sobre a fase de transio entre instncias dificeis e simples.

Ateno que os resultados podem ser mal lidos. Com 50 elementos no grfico no aparece nenhuma
instncia simples, ou seja, que se resolva em menos de 1 segundo. Isso no quer dizer que no existam
instncias simples, apenas que o nosso gerador no as gera, uma vez que tivemos o cuidado de manter
equilibrado o nmero de elementos em cada seleco. Caso tivesse sido utilizada a primeira verso do
gerador, teriamos muitas mais instncias simples, nubelando os grficos.
www.moodle.univ-ab.pt//print.php?id 77/85
26-01-2010 name

Este algoritmo fica validado em termos prticos para resolver qualquer instncia at 40 elementos. Este
tipo de informao no nos d uma anlise puramente analtica, que resultaria a informao de que o
algoritmo tem complexidade O(2^n).

Suponhamos agora que desconfiava que o algoritmo iria correr mais rpido se escolher primeiro os
elementos maiores e s depois os menores. H hiptese de implementar isso facilmente, basta que a
instncia seja ordenada antes de arrancar com o algoritmo. Tem tambm que comparar essa opo com
a actual, uma vez que a alterao requer mais tempo a ordenar, o que poderia no compensar.

No Partition h que adicionar um parmetro (no mtodo "Reset"), que de omisso est a 0 e se for 1 a
instncia ordenada: value.Add(0); name.Add("Ordenar"); description.Add("0 - no ordenar; 1 -
ordenar"); min.Add(0); max.Add(1);

No mtodo "Run", antes de chamar partition, mandar remover os zeros e ordenar. No esquecer de
adicionar o zero no fim, para ficar uma instncia vlida, no caso de se gravar. O ltimo comando passa a
ser antecedido por: if(value[0]==1) { if(total%2==0) { instance.Remove(0); instance.Sort();
resultado=partition(instance.Count()-1,0,total/2); instance.Add(0); } else resultado=0; } else [ltimo
comando]

Agora basta compilar e no mesmo ficheiro do EngineTester, no conjunto de parmetros de Partition


colocar o primeiro parmetro a 0, e duplicar este conjunto de parmetros, ficando Partition2, e colocar o
primeiro parmetro a 1. No engine Partition, h que colocar ambos os conjuntos de parmetros.

www.moodle.univ-ab.pt//print.php?id 78/85
26-01-2010 name

Naturalmente o nmero de corridas a efectuar duplicam, passa agora a 480 corridas, mas permite fazer a
comparao dos desempenhos com e sem a ordenao. Pode mandar correr aps limpar os resultados
actuais, que levar tempo, e os grficos fazem-se com as corridas em curso.

Pretende-se agora uma vista tipo a anterior, mas apenas para o caso do conjunto de parmetros ser
Partition. Para tal h que na dialog de base selecionar o conjunto de parmetros Partition, e criar uma
vista, respondendo sim pergunta de ser restrito ao conjunto de parmetros Partition. Apague desde j
todas as colunas excepto o tempo "1-3".

Seleccione agora o conjunto de parmetros Partition2 e crie uma vista, respondendo sim no s
pergunta de ser restrito ao conjunto de parmetros Partition2, como tambm a fundir com a vista
anterior. Apague tambm aqui as colunas "1-3", ficando apenas com duas linhas, com a informao do
tempo gasto em ambas as opes.

Agora pode construir um scatterplot e comparar directamente os tempos gastos num caso e no outro.
Neste caso pode-se ver que o desempenho do algoritmo piora claramente. Se houver dvidas de qual
o eixo com as novas opes, bastar abrir a vista do tamanho vs tempo e verifica-se que os resultados
pioraram na globalidade.

www.moodle.univ-ab.pt//print.php?id 79/85
26-01-2010 name

Pode-se parar a corrida, j que agora suspeita-se que invertendo a ideia d bom resultado, ou seja,
processar primeiro os nmeros mais baixos e depois os mais altos. Embora intuitivamente a primeira ideia
faa mais sentido, no campo dos testes h que olhar para os resultados.

Dado que a inverso no est implementada, h que incluir aps a ordenao (comando instance.Sort();)
cdigo para inverter a instncia: for(int i=0,j;i<instance.Count()/2;i++) { j=instance[i];
instance[i]=instance[instance.Count()-i-1]; instance[instance.Count()-i-1]=j; }

Ao mandar correr, observa-se que at a actual dimenso das instncias, de 30 a 60 elementos, no est
convenientemente dimensionada para o mtodo ordenar, dado que todas as instncias so resolvidas,
levando a mais difcil pouco mais de 3 segundos. Haver agora que passar este parmetro a ter um valor
fixo, deixando de ser parmetro, ou pelo menos o valor de omisso passar a ser 1, em vez de 0.

www.moodle.univ-ab.pt//print.php?id 80/85
26-01-2010 name

O processo repete-se, voltando a identificar novo teto do algoritmo, e volta-se a testar novas ideias. Sem
EngineTester, quanto tempo levaria a montar as corridas, fazer os grficos e a reagir? Provavelmente
demasiado tempo, e ideias para melhoramento tivessem ficado por testar dado o custo de fazer
novamente todas as anlises.

Muitas vezes faz-se tantas anlises que se perde a origem de algumas anlises. No EngineTester poupa-
se tambm no facto de se conseguir explicar como se fez cada anlise, dado que o documento
EngineTester tem toda a informao sobre como feita cada anlise, e est sempre pronto a refaz-la.

Paramos por aqui, o leitor pode completar a anlise de forma a concluir em termos prticos at que
instncias pode ser utilizado este algoritmo com sucesso.

Foram demonstradas as principais funcionalidades do EngineTester, embora algumas delas no com o


detalhe desejado. Esperamos no entanto que os exemplos de engines e anlises dados no captulo
seguinte sejam suficientes.

www.moodle.univ-ab.pt//print.php?id 81/85
26-01-2010 name

7 - Instalao e Manuteno
Aps o sistema construdo e devidamente testado, resta colocar o sistema em utilizao. Para tal h que
formar os utilizadores do sistema e construir documentao necessria para que o sistema possa ser
utilizado com sucesso.

7.1 Instalao
A instalao no deve ser efectuada sem uma documentao. O sistema pode ser facilmente instalado
pela equipa de desenvolvimento que acabou de desenvolver o software, no necessita naturalmente
nenhuma documentao. O problema quando o hardware necessitar de ser actualizado, ou o sistema
operativo, e as pessoas envolvidas no desenvolvimento da aplicao esto em outros projectos ou em
outra empresa.

A documentao deve descrever o processo de backup, e mais importante, o processo de restore de


todo o sistema. Forar um ou outro restore de supresa, de forma a conhecer o que acontecer numa
situao de emergncia, uma atitude sbia. boa prtica no caso de sistemas essenciais, existir uma
mquina com o sistema instalado, pronta a ser utilizada caso exista algum problema com o sistema em
produo. Assim possvel testar as actualizaes antes de estas serem feitas no sistema em produo.

7.2 Formao de Utilizadores


A formao de um utilizador dever incidir primeiramente pelas operaes bsicas e mais frequentes do
sistema, evoluindo para as operaes mais complexas e menos frequentes. A formao pode relacionar a
forma como as operaes so efectuadas no sistema actual, e como sero efectuadas no sistema novo.
Um utilizador precisa apenas de saber o que pode fazer com o sistema e como utiliz-lo. No necessita
de saber detalhes de como o sistema funciona internamente.

Para alm dos utilizadores do sistema, h tambm os operadores ou administradores, que efectuam
operaes de administrao do sistema. A formao dos administradores deve ser direccionada ao
funcionamento interno do sistema, e s operaes que tm de ser efectuadas regularmente para que este
funcione correctamente. Algumas dessas operaes podem ser: dar acessos a utilizadores; fazer backups
do sistema; instalar novos mdulos. Os administradores tm tambm de dar apoio aos utilizadores do
sistema, de modo que tm tambm de ter a formao dos utilizadores.

Poder haver utilizadores que utilizam o sistema apenas esporadicamente, ou apenas para consulta,
devendo haver uma formao mais leve para esses utilizadores.

A formao deve ter em ateno os conhecimentos prvios dos utilizadores. Por exemplo, caso existam
utilizadores no familiarizados com computadores, necessrio um curso de iniciao a esses
utilizadores. A formao deve ser dividida em unidades pequenas.

A formao no deve ser apenas numa sesso na entrega do sistema. Deve estar disponvel sempre que
o utilizador necessitar, por diferentes formas: manual impresso; manual online; sesses de formao;
utilizadores experientes.

7.2.1 Manual Impresso

Os manuais impressos tm de ser completos e portanto acabam por serem volumosos. Normalmente so
considerados pelos utilizadores como no essenciais, muitas vezes porque pretendem fazer apenas
www.moodle.univ-ab.pt//print.php?id 82/85
26-01-2010 name
operaes simples e no sabem como encontrar rapidamente a informao que necessitam, e no
querem perder muito tempo a ler o manual. Os manuais devem ser consultados quando h dvidas, ou
antes de uma operao pouco frequente, e devem ter hiptese de serem utilizados tanto em modo de
consulta rpida (manual de referncia), como em modo de formao (manual tutorial).

Um manual de utilizador deve conter no mnimo os seguintes elementos:

Um esquema geral com as principais funcionalidades do sistema e de como se relacionam entre si;
Uma descrio dos dados necessrios a cada funcionalidade do sistema;
Uma descrio dos dados produzidos por cada funcionalidde do sistema;
Uma descrio de caractersticas especiais de cada funcionalidade do sistema.

7.2.2 Manual Online

O manual online, juntamente com nomes de menus e icons sugestivos, e toda a interface do sistema no
geral, so outra forma de formao, normalmente a mais utilizada. O manual online pode ser uma cpia
do manual impresso ou uma verso reduzida deste, mas dever ter hiptese de ser acedido de diversos
locais com ligaes directas pgina do manual onde descrito o comando que poderia ser executado.
No manual impresso as referncias a outras zonas do manual so feitas por indicao da pgina, no
manual online estas devem ser atravs de hiper-texto, de forma a obter-se a pgina distncia de um
clique.

7.2.3 Sesses de Formao


Na formao, muitos utilizadores preferem demonstraes do software. As demonstraes podem ser
feitas presencialmente, ou gravadas, e normalmente focam um aspecto do sistema de forma a no serem
demasiado longas. As demonstraes funcionam melhor para muitas pessoas que mantm a ateno
durante mais tempo em apresentaes verbais do que em apresentaes escritas. Deve-se encorajar a
participao dos utilizadores nas demonstraes.

7.2.4 Utilizadores Experientes


Na entrega do sistema, a formao prvia de utilizadores avanados pode facilitar a formao dos
restantes utilizadores, que assim podem ser assistidos pelos utilizadores avanados durante a formao e
aps a formao. Este tipo de abordagem aconselhado em sistemas complexos, em que se anteveja
que a maior parte dos utilizadores venha a ter grandes dificuldades a utilizar o novo sistema.

7.3 Manuteno
Aps o sistema estar em funcionamento h sempre operaes de desenvolvimento que se necessita de
fazer, para no s corrigir falhas que se encontrem entretanto, como para desenvolver novos mdulos
que venham a revelar-se importantes. A manuteno a actividade de correco ou desenvolvimento
feita aps o sistema estar em funcionamento. Tudo o que for sendo feito deve ficar registado de forma a
poder ser repetido quando se fizer actualizaes ao sistema.

Com o sistema em funcionamento, ao longo dos tempos o custo de manuteno pode ir aumentando. H
que decidir o ponto em que se toma a deciso de substituir o sistema actual por um novo. Para tal h que
analisar: custo de manuteno; fiabilidade do sistema; capacidade de evoluo do sistema; alternativas no
mercado.

Para basear as decises deve-se calcular a fiabilidade, disponibilidade e manutenabilidade do software,


www.moodle.univ-ab.pt//print.php?id 83/85
26-01-2010 name
bem como registar outros indicadores de manuteno.

Caso se mantenha o sistema em funcionamento existem os seguintes tipos de manuteno:

Manuteno correctiva resoluo de falhas que ocorram no dia-a-dia;


Manuteno adaptativa implementao de mudanas em componentes necessrias devido a uma
outra mudana no sistema;
Manuteno aperfeioativa melhoramentos efectuados no sistema sem que tenham origem em
falhas;
Manuteno preventiva alterao do sistema de forma a torn-lo mais robusto, sem que tenha
no entanto existido falhas.

Naturalmente que sistemas de grande dimenso e essenciais ao negcio da empresa, requerem recursos
humanos atribudos permanentemente manuteno.

7.3.1 Fiabilidade, Disponibilidade, Manutenabilidade


A fiabilidade do software est relacionada com a probabilidade de este falhar. Um software altamente
fivel tem uma baixa probabilidade de falhar. A disponibilidade do software est relacionada com a
probabilidade do sistema estar operacional num dado momento. A manutabilidade do sistema est
relacionada com a facilidade de manuteno do software.

H basicamente dois tipos de incertezas, a primeira do tipo 1, reflecte o nosso desconhecimento de


como o sistema ser utilizado, e portanto impossvel conhecer quanto tempo levar at prxima falha.
O segundo tipo de incerteza, do tipo 2, reflecte a nossa falta de conhecimento sobre as implicaes no
resto do sistema da correco de uma falha.

Estas grandezas podem ser medidas, desde que para tal se recolha a informao necessria:

Tempo para falha o valor mdio "Mean Time to Failure" MTTF;


Tempo de reparao o valor mdio "Mean Time to Repair" MTTR.
Com estes valores pode-se tambm calcular o valor mdio do tempo entre falhas: "Mean Time
between Failures" MTBF.

Com base nestes valores mdios pode-se calcular rcios para que o valor 1 seja o ideal e o valor 0
indesejado, para as trs grandezas fiabilidade, disponibilidade e manutenabilidade:

fiabilidade;
disponibilidade;
manutenabilidade.

7.3.2 Indicadores de Manuteno


Para que exista algum controle sobre a manuteno, devem ser registadas informaes bsicas das falhas
encontradas. No clculo do tempo de reparao deve ser descriminado as seguintes parcelas:

tempo que levou a ser reportado um problema;


tempo perdido em processos administrativos;
tempo necessrio para analisar o problema;
tempo necessrio para especificar as mudanas a fazer;
tempo necessrio para fazer as mudanas;
www.moodle.univ-ab.pt//print.php?id 84/85
26-01-2010 name
tempo necessrio para testes;
tempo necessrio para documentar.

H tambm indicadores de complexidade do cdigo a manter, que se podem calcular de forma a ter uma
ideia dos custos de manuteno futuros. Utiliza-se normalmente o nmero ciclomtico para complexidade
de cdigo. H tambm a possibilidade de calcular indicadores sobre documentao, de forma a
contabilizar a legibilidade do texto. Esses indicadores no esto no entanto muito desenvolvidos.

O nmero ciclomtico o nmero de caminhos diferentes no cdigo. Mostrou-se que esse nmero
igual ao nmero de comandos de deciso mais 1. portanto muito fcil de calcular, mesmo para uma
grande quantidade de linhas de cdigo.

O nmero ciclomtico permite dar uma ideia da complexidade de um bloco de cdigo, mas ao decidir
efectuar uma alterao ao cdigo, o custo estimado nessa alterao poder passar no s pelo mdulo
afectado, mas tambm pelos mdulos que este interage, e pela reviso da documentao associada. Os
testes que esto ligados aos mdulos afectados, tm de ser refeitos, e a documentao actualizada.
Todos estes custos tm de ser levados em considerao, para saber se vale a pena efectuar a correco,
ou se por outro lado se deixa como est. Notar que aps identificar um problema, a sua resoluo
poder passar por corrigir apenas o cdigo, mas pode tambm passar por alterar o desenho, ou mesmo
os requisitos, levando a custos muito superiores nestes dois ltimos casos.

7.3.3 Rejuvenescimento de Software

O rejuvenescimento de software destina-se a aumentar a qualidade do software em manuteno com


vista em reduzir os custos de manuteno futuros. H diversas estratgias para tal:

re-documentao efectuar uma anlise ao cdigo, de forma a produzir documentao explicativa


do cdigo;
re-estruturao efectuar uma anlise ao cdigo, de forma a re-estruturar o cdigo para uma
estrutura mais correcta;
engenharia inversa efectuar uma anlise ao cdigo, de forma a gerar o desenho e especificaes
que lhe deram origem;
re-engenharia efectuar uma anlise ao cdigo, de forma a gerar o desenho e especificaes que
lhe deram origem, e com estas gerar novo desenho e novo cdigo.

"Software Engineering, theory and practice", second edition, Prentice Hall, Shari Pfleeger, pg. 403-407,
448-460, 464-502

www.moodle.univ-ab.pt//print.php?id 85/85