Através deste roteiro, você poderá desenvolver sistemas próximos da perfeição, acredite!
I - CERTO: A - Se um programa não estiver certo ele não cumpre as suas finalidades. B - Um programa certo, além de fazer o que deve, não pode fazer o que não deve. Por exemplo: Ao calcular a área do triângulo de lados 4, 1, 1; o programa deve dizer que os lados não formam um triângulo e não dar um valor como resposta. Para isto, devemos sempre estabelecer o domínio de validade dos dados de entrada do algoritmo e testar a validade da desses dados. C - Não é fácil fazer um programa certo, pois não há técnica conhecida que garanta a exatidão deste. Podemos mostrar que um programa está errado, mas não podemos mostrar que ele está certo. As consistências, tanto de dados como do programa, deverão estar restritas as necessidades dos mesmos. Excesso de consistências e consistências que consistem outras consistências não agregam nada ao programa, fazem ele ficar mais lento e só servirão para proliferarem bugs e falhas no mesmo. Procure fazer o tratamento das exceções que podem vir a ocorrer no programa. Se você conheçe uma área de código que é propícia a erros e falhas de excução (Ex: Uma variável de valor flutuante pode receber um dado inválido), você pode tratar esta área para, caso ocorra um erro, seu programa não perca o fluxo de execução ou seja abortado pelo sistema operacional. Vejamos um exemplo disto:
procedure TForm1.FormCreate(Sender: TObject);
![]() Toda instrução passivel de erro deve ser tratada com uma mensagem de erro para o usuário. Após a elaboração do programa, passamos à fase de depuração que é quando tentamos descobrir erros no mesmo. Existem técnicas para se testar um programa e abaixo damos algumas dicas: 1) Um programador nunca deve testar seu próprio programa, pois o teste é uma tarefa destrutiva e o programador geralmente não gosta de destruir o que fez. Além do mais ele já sabe perfeitamente como operar e como lançar os dados no programa o que impede que ele teste o comportamento do mesmo no caso de faltar lançar determinados dados ou lançar dados inválidos ou de outra forma. Isto pode omitir uma serie de possíveis bugs que estejam ocultos ou que somente se manifestam em uma determinada situação. 2) Um teste de um programa tem sucesso quando se acha um erro. Não tente mostrar que o programa está certo, pois isso, além de ser uma tarefa impossível, irá mascarar um problema que se manifestará futuramente comprometendo a credibilidade do sistema. Se os testes foram feitos e nenhum erro encontrado, passe o programa para outra pessoa testá-lo para ver se o resultado é condizente com o primeiro teste. Teste "caixa preta": É quando examinamos um programa por suas especificações, sem olhar o código. Ao realizar um teste, tentamos explorar os casos limites e forçar o programa em seus limites máximos e mínimos de dados, tanto para entrada como para saída, para ver seu comportamento. Esta técnica é conhecida como "valores limites": Dividimos os dados em classes, segundo o sentimento do programador que vai testar o programa. Uma classe para cada domínio de dado e, se o testador desconfiar que o programa se comporta de modo diferente em uma classe, divide-a em duas classes. Para cada classe de dados, testamos os valores limites do domínio: o maior valor, o menor valor, um valor fora do domínio imediatamente abaixo e imediatamente acima do domínio. Para cada classe de dados, sempre testamos um valor dentro da classe e um fora da classe. Aplicações que farão uso de protocolos de rede (Aplicações Client/Server ou aplicações para WEB), Deverão ser testados o número máximo de conexões para qual o mesmo foi projetado e analisar se os dados vindos de uma conexão condizem com sua origem. O mesmo se aplica para o retorno. Sempre que uma conexão com seu programa encerrar, ela deverá estar disponível para uma nova requisição imediatamente. Estas regras se aplicam para aplicações MultiThreads, aplicações em 3 camadas (Ex: Midas) e aplicações distribuídas também. 3) Existem duas categorias de erros: Os Implícitos e os Explícitos. Os Explícitos são aqueles que são vistos facilmente pelo programador. São erros de sintaxe, erros de atribuição ou conversão de valores. Enfim, são erros que o programador detecta ao visualisar o código fonte ou mesmo vendo o programa funcionando. Os Implícitos são os erros de lógica. São mais dificeis de serem encontrados, requerem uma maior análise do comportamento do programa em determinadas circunstâncias, para que ele possa ser rastreado e causam um estrago muito maior do que os Explícitos. Normalmente as costumeiras falhas de segurança encontradas em aplicativos Microsoft ou outros, são erros desta natureza. Sempre que você detectou um erro implícito, você deverá documentar todos os passos usados no rastreamento dele, bem como as causas, a forma como ele se manifesta e as consequências deste referido erro. Erros implícitos não existem para serem corrigidos e esquecidos e sim para serem corrigidos e documentados. Documente também as atividades, entrada de dados e operações que o usuário fez quando este erro se manifestou. Elas serão necessárias nos testes após as correções e na análise e desenvolvimento de futuros programas. 4) Devemos ter uma atenção especial com tabelas (array's) e listas (ponteiros). Testar sempre o primeiro elemento, o último elemento, colocar um valor quando a tabela estiver vazia, colocar o último elemento e colocar um elemento a mais, para ver se o programa detecta. Para listas, testar para inserir o primeiro elemento, inserir antes do primeiro elemento, inserir depois do último, etc. O mesmo para a remoção: retirar o primeiro elemento, apagar o último, apagar um elemento que é único na lista, etc. Teste "caixa branca": é quando examinamos o fonte do programa. Geralmente os teste caixa branca são muito mais eficientes que os caixa preta. A metodologia mais empregada é a conhecida como "revisões estruturadas" (walkthrought) em que um grupo de pares (pessoas no mesmo nível) se reúnem, organizadamente, com o objetivo de descobrir erros num programa (ou mesmo um outro produto qualquer. O mecanismo das revisões estruturadas está bem descrito no livro "Revisões Estruturadas" de E. Yourdon. D - A maior ferramenta que um programador dispõe para fazer um programa certo é chamada SIMPLICIDADE. Esta é a meta de um bom programador, fazer um programa SIMPLES E OBJETIVO. II - INTERFACE AMIGÁVEL: Com o desenvolvimento dos sistemas baseados em interfaces visuais, como o Windows, fica cada vez mais importante uma aparência agradável e a facilidade de se lidar com as telas e comandos do sistema. A essas qualidades chamamos de interface amigável e fazem parte do estudo da Interface Homem-Máquina. Uma interface neste padrão, deve fazer com que o usuário se sinta bem ao mexer com o sistema e o sistema transmita a ele uma sensação de que é facil de ser operado. Deve ter comandos intuitivos e visual caprichado. Uma interface amigável é um ponto decisivo no sucesso de um produto. Muitas vezes é o responsável pelo sucesso do produto. O que você prefere, Netscape ou Explorer? Windows ou Linux? Para responder a esta pergunta certamente você levará em consideração a interface dos dois sistemas. Isso, muitas vezes, é mais importante que o próprio desempenho do sistema. A recomendação é que uma interface deve ser tão próxima quanto possível de outras interfaces que o usuário já esteja acostumado. Normalmente, em uma grande empresa, há um padrão de interface a ser seguido por todos os aplicativos. Isso facilita o uso e dá uma identidade ao fabricante. Como atualmente o Windows é um padrão universalmente aceito, recomendo que procure, tanto quanto possível, seguir o "jeitão" dos programas Windows. Se você não gostar do padrão Windows, então crie seu próprio padrão mas que esteja próximo dos padrões aceitos pelo mercado. A construção de uma interface amigável é muito trabalhosa e geralmente precisa de auxílio de outras especialidades, principalmente da área de comunicação visual. Esse tema é um ponto importante e tanto o analista como o programador não podem se descuidar dele. Interfaces muito cheias de animações e imagens, ao contrário do que se pensa, criam inúmeras dificuldades ao usuário em navegar ou clicar em um botao específico no programa ou consultar uma informação, além de transimitir uma impressão de que o mesmo é complexo e dificil de ser operado. A poluição visual é uma das maiores fontes de resistência dos usuários aos novos sistemas de computador e uma dos maiores causadores de erros de entrada de dados, devida a confusão visual que ele proporciona ao seu operador. Evite ao máximo usar Edits, Labels e botões multicoloridos ou piscantes. Somente use-os com critério e para realmente chamar a atenção do usuário para um campo ou dado imprescindível. Animações e imagens devem ser usadas restritamente e deverão, em caso de uso, representar o propósito da janela em uso ou de uma operação específica nesta. Ou então apenas conter o logotipo do sistema ou da empresa. Devem estar também limitadas a uma imagem por janela e sempre colocada em local distante da área de entrada ou saída de dados. Procure usar sempre as cores padrão do sistema operacional. Cores fortes, como o vermelho, somente deverão ser usadas em locais que se pretende chamar a atenção do operador. ![]() O WinMx, software P2P muito usado para baixar MP3, é um exemplo de interface pouco amigável. Suas telas são confusas e cheias de botões espalhados e os dados recebem cores variadas conforme a circunstância. Algumas recomendações a serem seguidas:
![]() Os subníveis de Menus Pop-Up não devem ter mais do que um submenu. Abaixo vemos um mau exemplo de Menus em cascata infinita que dificulta o acesso ao módulo respectivo
Existem regras básicas de layout: - Devemos evitar colocar os componentes e controles de um só lado do form (senão seu desenho fica "pesado" para a esquerda ou para a direita. - Alinhar os Edits e Labels. - Não aglomere muito os Edits, procure deixá-los separados de forma que transmita clareza e leveza da janela ao usuário. - Em cadastros muito extensos deve-se usar panels separando alguns grupos de Campos. - Em cadastros com muitas entradas de dados, separe-as por assuntos dividindo a área de form em Tabs ou PageControls. - Se colocar os campos horizontalmente coloque os controles na vertical (e vice-versa). - Use Ícones e/ou imagens do mesmo tamanho e de cores compatíveis entre eles (não colocar um muito colorido entre vários com somente 3 ou 4 cores). - Prefira letras mais escuras que o fundo. Letras muito claras podem criar confusão ou dificuldade de interpretação por parte do usuário. - Procure sempre que possível deixar seu formulário com uma aparência o mais semelhante possível com a do sistema operacional. Isto facilita e já deixa o usuário pré-familiarizado com o mesmo. No mais observe os formulários de outros sistemas e tire proveito das boas idéias. III - CLAREZA: A - A maior parte do dinheiro gasto na vida de um programa é para modificá-lo. Um programador não deve pensar que seu programa é ou será definitivo. Deve, ao programar, pensar no programador (muitas vezes ele próprio) que vai modifica-lo futuramente. B - A maior ferramenta para a clareza de um programa é também a SIMPLICIDADE. C - A documentação também é uma arma importante que o bom programador recorre para aumentar a clareza. Abaixo damos algumas dicas para a documentação de um bom programa: Para variáveis:
Para constantes:
Para expressões aritméticas:
4) O uso de parênteses em expressões matemáticas é extremamente fundamental uma vez que é através deles que o compilador irá determinar a ordem de processamento das operações matemáticas. Ex: 5 x (A + (B * 54,5) / 3) - 2 / 3500 Neste caso a primeira operação a ser processada será a (B * 54,5) para em seguida ser a (A + ResuladoDaPrimeiraOperação / 3) para aí sim o restante da expresão. Bastará um parenteses esquecido ou colocado em outro lugar para o resultado da expressão já ser outro. O problema vai ser você achar este erro depois de um mês que o programa ficou pronto. Para expressões lógicas:
Para comandos if:
Para comandos de repetição:
a) Se já sabe antes de começar o loop quantas vezes ele será executado, use o for. Dê preferência ao for que é mais simples. b) No caso de termos saída de condição, por exemplo, rode 10 vezes ou até achar um elemento, não use o for, use while ou repeat. c) Se a condição de escape do loop é calculada dentro do loop, use o repeat. d) Se o loop puder ser executado zero vezes, use o while. e) Entre o while e o repeat: o while é mais geral, pode ser executado zero vezes, porém a condição de escape geralmente é feita na negativa (o que é ruim). O repeat é mais intuitivo e mais fácil do programador iniciante entender. A escolha entre um e outro comando, quando for indiferente, fica por conta da preferência de cada programador. 2) Use indentação para ressaltar o corpo do loop. 3) Em um comando for, não mude o valor da variável de controle, nem das variáveis envolvidas no cálculo do valor máximo do loop. Especialmente, não force a saída do comando atribuindo valor limite à variável de controle. Neste último caso, prefira um comando while ou repeat. 4) Existem alguns comandos, oriundos de linguagens antigas, que são colocados nas linguagens modernas apenas por uma questão de compatibilidades. O GOTO mesmo é um deles e equivalia aos for ou whiles atuais. Tais comandos nunca que estão descartados de serem usados, mas devem ser usados em casos muito especiais, pois tendem a causar mais problemas do que soluções em um programa. O comando GOTO faz uma quebra da sequência lógica do seu programa, que é processado no sentido descendente (de cima pra baixo). Quando seu programa encontra uma instrução goto, ele saltará deste ponto para o lugar onde foi especificado na instrução, colocando o processamento em um outro ponto qualquer. Quando ele é implementado incorretamente, pode fazer seu programa entrar em loop infinito ou passar a se comportar de outra forma quando uma certa condição se fizer presente. Quando você usar o GOTO em seu programa, faça testes exaustivos com todas as possibilidades para ver se o salto está dentro do previsto na sua lógica. Indentação:
function RemoveCifrao(Const Text: string): String;
S := '';
for I := 1 To Length(Text) Do
result := S;
end;
Isto facilita e deixa o código mais claro de ser lido e interpretado pelo programador. Outras recomendações:
2) Evite macetes de programação para poupar comandos, tempo de execução ou espaço de memória. Tais macetes podem fazer seu programa ter múltiplos comportamentos conforme as situações que ele propiciar e conforme o que ele estiver processando. A otimização de algorítmos deve ser feita usando o raciocínio lógico e não macetes. 3) Evite qualquer tipo de improviso (Gambiarras), ainda que ele seja "uma coisinha atôa" para ser implementada de última hora. Sem dúvida alguma, esta é a maior fonte de proliferação de bugs no programa. 4) As funções e procedimentos são partes do código que serão usadas mais de uma vez no programa. Isto faz com que o código final fique menor, mais façil de ser customizado e mais prático para se dar manutenção. Só que do outro lado, toda vez que seu programa tiver que executar uma função ou procedimento, ele para, vai ser empilhado para executar a rotina e depois volta a ser executado. Portanto quanto mais funções e procedimentos ele tiver, mais lento ele ficará. Seja criterioso naquilo que irá virar procedimento ou função, se realmente é necessário e se o código será usado mais vezes. Atente para funcões recursivas que nem sempre são convenientes e que são grandes causadoras do Estouro de pilha. Comentários:
a) O nome da empresa
2) Sempre coloque um comentário nas procedures e functions dizendo o que ela faz, qual o significado dos parâmetros e domínio de validade dos algorítmos. 3) Quando for necessário fazer um trecho de algorítmo complicado, explique o que foi feito com comentários e o que o algorítmo faz. 4) Faça uso constante dos comentários, porém não comente demais e nem comente o óbvio. É uma boa norma de programação colocar trecho do algoritmo em alto nível antes do trecho de programa correspondente. 5) Se um trecho do algoritmo teve de ser expandido, coloque essa expansão como comentário perto do trecho do programa correspondente. 6) Colocar como comentário o significado de uma variável ou constante junto com a definição da mesma, desde que não seja óbvio. 7) Se uma parte do algorítmo precisar ser eliminada ou modificada, não apague-a para reescrever de novo. Neutralize a parte dispensável com comandos de comentario, pois caso você necessitar desta parte novamente, ela estará disponível. IV - TEMPO DE EXECUÇÃO: A - Só nos preocupamos com o tempo de execução quando for necessário. Por exemplo: um programa leva 12 horas para dar a resposta e os micros devem são desligados após o expediente. B - Geralmente um programa simples é eficiente. Complicações e implementações desnecessárias geralmente aumentam o tempo de execução. Novamente voltamos à principal qualidade do programa que é ser SIMPLES E OBJETIVO. C - A melhoria de um programa é feita depois do programa estar pronto e certo, e somente se for necessário. Com o programa ainda em desenvolvimento, é uma faca de dois gumes pois o programador, na tentativa de otimizar algorítmos que ainda não estão prontos, pode se perder na interpretação lógica dele. É outra fonte de proliferação de bugs no programa. D - Se o programa está lento por causa de entrada/saída, será necessário redefinir os arquivos que usa, para que os acessos sejam feitos de modo mais eficiente. Abrir tabelas no ato da execução do programa e somente fechá-las no encerramento deste, nada mais faz a não ser propiciar a perda de dados devido a piques de energia ou falhas no sistema operacional, além de comprometer a performance do programa. Tabelas somente deverão ser abertas quando forem usadas e, logo após seu uso, fechadas. E - Somente crie objetos (Forms, Stringlists e Listas encadeadas) quando for realmente usá-los e destrua-os logo após o seu uso. Não há a mínima necessidade deles serem criados no ato da execução do programa para ficarem no aguardo de serem usados em apenas um único módulo que é raramente acessado. F - Se o programa for trabalhar em rede ou em modo compartilhado, evite bloquear toda a tabela. Somente o registro a ser mexido deve ser reservado ao programa, e mesmo assim, somente no momento de ser editado. G - Se o programa demora por cálculos, devemos identificar o loop mais interno do programa e melhorar somente esta parte. Estudos feitos em vários programas com muito cálculo mostraram que cerca de 90% do tempo de execução é gasto em apenas 3% de código do programa. Esta parte é chamada loop mais interno (inner loop). Em máquinas de grande porte há softwares especiais para identificar essas partes, mas dá para identificar o inner loop apenas examinando o programa. Qualquer melhoria feita fora desses 3% de código é inoperante. É nesse pequeno trecho que nossa atenção deve ser concentrada. Nesta parte de cálculos, devem ser evitadas também, funções e procedimentos pelos motivos já anteriormente citados. V - ECONOMIA DE MEMÓRIA: A - Só nos preocupamos com a economia de memória quando for necessário. Por exemplo: algumas versões antigas do Pascal tem um limite de 64k bytes para cada estrutura. Se nosso programa não couber nesses 64k temos de dar um jeito para que caiba. B - Novamente: a simplicidade conduz a programas menores e com menos variáveis. Geralmente quanto menos variáveis um programa usar, mais simples será e menos bytes de memória ele consumirá. A preocupação deve então ser com a simplicidade e não com a economia de memória. Portanto jamais ignore as mensagens de aviso do compilador (Os Warnings) que a variável X ou o procedimento tal foi declarado mas nunca usado, porque, para outra coisa isto não vai servir se não para consumir parte da memória. Somente crie e aloque variáveis que são realmente necessárias. C - Certifique-se sempre de que TODO OBJETO QUE ESTÁ SENDO CRIADO NO SISTEMA ESTÁ SENDO DESTRUÍDO APÓS O SEU USO. QUE TABELAS QUE FORAM ABERTAS FORAM FECHADAS APÓS O USO. O maior drama do programador é quando, após o programa ser finalizado, o computador fica lento e sem memória, fenômeno este conhecido como "vazamento de memória". Isto acontece quando o programa requisita uma determinada quantidade de memória para rodar e ao ser finalizado ele devolve menos do que pediu. Atente também para recursos de hardware, que foram requisitados pelo seu programa, e que deverão estar disponíveis para qualquer outro software após a sua finalização. D - Junto com a sua ferramenta de desenvolvimento, costuma-se vir outras de depuração e monitoramento de memória. No caso do Delphi, temos o Winsight, o Turbo debugger e o SQL Monitor. Procure aprender a usá-las pois elas são muito úteis na detecção de causadores de vazamento de memória, bloqueio indevido de tabelas ou de recursos de hardware que estão inascessíveis após serem usados pelo seu programa. A WEB também está cheia de ferramentas Freeware e Shareware que auxiliam muito o programador em eliminar tais anomalias. ![]() O WinSight é uma ferramenta que vem junto com as ferramentas da Borland e permite que você monitore janelas que estão abertas. Muito útil para sabermos de recursos que estão na memoria mesmo após o programa ter sido finalizado. |
E-Mail: walterchagas@yahoo.com |
![]() |