Histórico da Página
Composition Setup |
---|
import.css=/download/attachments/327912/newLayout.css |
Portuguese | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Documento: Guia de boas práticas - Legibilidade de código
|
Tipo de Programa | Programação estruturada | Programação orientada por objetos |
Formulários | Na estrutura do código e nas validações do campo | No consumo do framework |
Consultas | Na estrutura do código | No consumo do framework |
Relatórios | Na estrutura do código | No consumo do framework |
Processamento | Na estrutura do código | No consumo do framework |
Biblioteca de regras de negócio | Preferencialmente | Somente sob consulta a GDP de Framework |
Web Services | Indisponível | Preferencialmente |
Neste momento você deve ter percebido que o uso de programação orientada por objetos é controlada. Isto se deve a característica do nosso Server Application. O Server Application utilizado pela Linha Microsiga Protheus compartilha numa única instância/slave, várias conexões de usuário. Estas conexões dividem a memória desta instância/slave e seus limites. Por esta razão e pelo fato da programação orientada por objetos consumir mais memória que a programação estruturada, seu uso é restrito apenas onde há vantagens significativas.
Para a correta compreensão deste tema, precisamos observar o cenário de trabalho de nossos programas. Uma instância/slave de uma aplicação de 32 bits tem alocação máxima de 1,8 Gbytes de memória, qualquer valor acima disto pode causar um GPF na aplicação e forçar o Sistema Operacional a derrubar a instância/slave.
A meta da linha Microsiga Protheus é possibilitar 30 usuários ativos em cada instância/slave, algo em torno de 61 Mbytes por usuário. Uma classe que represente uma interface ou regra de negócio em AdvPL consume em média 1 Mbyte de memória, muito em relação ao máximo de alocação que temos.
Muito bem, neste ponto você deve ter percebido que não é apenas com programação orientada a objetos que devemos ter cuidado. Devemos ter cuidado com qualquer estrutura que aloque ou possa alocar muita memória, tais como: XML´s, Array´s e grandes strings, mesmo utilizando programação estruturada.
A seguir veremos a formatação dos programas da Linha Microsiga Protheus.
Formatação dos programas
Os programas devem ser estruturados em blocos. Entende-se por blocos de programas os trechos que fazem alguma ação lógica ou seqüência de comandos. Todo bloco de programa deve ter uma única entrada e uma única saída, evitando-se assim o uso de desvios incondicionais, tais como loop, exit, etc.
O não uso de desvios incondicionais ( loop, exit, etc... ) é uma das principais diferenças entre a programa estruturada e sequêncial.
Os blocos devem ser documentados apropriadamente e para cada bloco temos uma forma de documentação e formatação:
· Área de identificação
· Área de declaração de variáveis e ajustes iniciais
· Corpo do programa
· Área de encerramento
Área de identificação
Todas as funções, classes e métodos, devem ser documentados e identificados. Lembre-se, trabalhamos em equipe, portanto continuamente iremos fazer e alterar códigos de outras pessoas. Um código documentado facilita a manutenção, reduz o tempo de desenvolvimento e reduz o risco de bug.
Toda vez que for criar uma nova função ou classe verifique se ela não existe. Tome como base o escopo da função e veja se realmente você tem domínio sobre esta função. Exemplo: uma função genérica deve ser desenvolvida e mantida pela GDP de Framework, uma função financeira, deve ser construída e mantida pela GDP de Controladoria, uma função de movimentação de estoque, pela GDP de Materiais, e assim por diante. Mesmo em customizações devemos seguir este padrão e privilegiar pelo uso de funções documentadas pela TOTVS, evitando-se assim custos desnecessários em migrações de versão ou atualizações do produto.
Acima podemos observar a área de identificação de uma função da Linha Microsiga Protheus. Note que ela é formada por tags que podem ser facilmente identificadas. Estas tags são utilizadas para integrar a documentação do código com o site de documentação da Linha Microsiga Protheus.
Na tabela abaixo destacamos a função de cada uma das tags
{Protheus.doc} | Identifica o inicio do bloco de documentação. Deve ser precedido do nome da função ou método e no parágrafo seguinte deve ter a descrição completa do bloco. |
@param | Parâmetros de entrada, listados na ordem de passagem. Exemplo: //---------------------------------------------------------- /*/{Protheus.doc} FWTeste1() Função teste @param cFederalId Informe. @param nErro Retorna. @param aIDs Retorna. /*/ //---------------------------------------------------------- Function FWteste1(cFederalId,nErro,aIDs) |
@protected | Se inserida indica que a função tem uso restrito pela GDP criadora e não pode ser reaproveitada em customizações e/ou integrações. //---------------------------------------------------------- /*/{Protheus.doc} FWTeste1() Função teste @protected /*/ //---------------------------------------------------------- Function FWteste1(cFederalId,nErro,aIDs) |
@author | Autor ou revisor do bloco //---------------------------------------------------------- /*/{Protheus.doc} FWTeste1() Função teste @author Eduardo Riera /*/ //---------------------------------------------------------- Function FWteste1(cFederalId,nErro,aIDs) |
@version | Versão da Linha de produto Microsiga Protheus em que o bloco teve inicio. Utilize a nomenclatura definida pela GDP de Framework, exemplo: //---------------------------------------------------------- /*/{Protheus.doc} FWTeste1() Função teste @version MP11.5 /*/ //---------------------------------------------------------- Function FWteste1(cFederalId,nErro,aIDs) |
@build | Versão mínima da Build do Application Server que o bloco é suportado. //---------------------------------------------------------- /*/{Protheus.doc} FWTeste1() Função teste @build 7.00.100812P - Sep 1 2010 /*/ //---------------------------------------------------------- Function FWteste1(cFederalId,nErro,aIDs) |
@deprecated | Se inserida indica que a função não possui mais manutenção e/ou foi substituída por outra, tendo seu uso depreciado. Recomenda-se assim a substituição pela nova função. //---------------------------------------------------------- /*/{Protheus.doc} FWTeste1() Função teste @deprecated /*/ //---------------------------------------------------------- Function FWteste1(cFederalId,nErro,aIDs) |
@see | Indica as funções que devem ser observadas pelo desenvolvedor antes do uso. “Veja também”. //---------------------------------------------------------- /*/{Protheus.doc} FWTeste1() Função teste @see FWTeste2,FWTeste3,FWTeste4 /*/ //---------------------------------------------------------- Function FWteste1(cFederalId,nErro,aIDs) |
@since | Data de criação da rotina //---------------------------------------------------------- /*/{Protheus.doc} FWTeste1() Função teste @since 9/10/1995 /*/ //---------------------------------------------------------- Function FWteste1(cFederalId,nErro,aIDs) |
@return | Indicador do retorno da função //---------------------------------------------------------- /*/{Protheus.doc} FWTeste1() Função teste @return ExpL: indica se a rotina foi executada corretamente. /*/ //---------------------------------------------------------- Function FWteste1(cFederalId,nErro,aIDs) |
@todo | Indicativo de função incompleta ou com pendências de desenvolvimento //---------------------------------------------------------- /*/{Protheus.doc} FWTeste1() Função teste @todo proteger a função de chamadas por customização. /*/ //---------------------------------------------------------- Function FWteste1(cFederalId,nErro,aIDs) |
@sample | Exemplo de uso do bloco |
@obs | Observação complementar ao bloco. |
Área de declaração de variáveis e ajustes iniciais
Nesta área devem ser feitos os ajustes iniciais, importantes para o correto funcionamento do programa. Entre esses ajustes iniciais se encontram declarações de variáveis, proteções e inicializações.
As variáveis devem ser declaradas seguindo a notação húngara. A notação húngara consiste em colocar prefixos nos nomes de variáveis, de modo à facilmente identificar seu tipo. Isto facilita na criação de códigos-fonte extensos, pois usando a Notação Húngara, você não precisa ficar o tempo todo voltando à definição de uma variável para se lembrar qual é o tipo de dados que deve ser colocado nela. Variáveis devem ter um prefixo de Notação Húngara em minúsculas, seguido de um nome que identifique a função da variável, sendo que a inicial de cada palavra deve ser maiúscula.
É obrigatória a utilização desta notação para nomear variáveis.
Notação | Tipo de dado | Exemplo |
a | Array ou Matrix | aValores |
c | Caracter ou String | cNome |
d | Data | dDataIni |
l | Lógico ou boleano | lContinua |
n | Numérico | nVlrConta |
o | Objeto | oMainWin |
x | Indefinido | xBuffer |
As variáveis de entrada devem ser protegidas e inicializadas. Para tanto, utilize o comando PARAMTYPE ou DEFAULT, conforme demonstrado no exemplo abaixo:
#INCLUDE “PARAMTYPE.CH”
//-------------------------------------------------------------------
/*/{Protheus.doc} New
Método construtor da classe
/*/
//-------------------------------------------------------------------
METHOD New( cID , bPre, bPost, bCommit, bCancel ) CLASS FWFormModel
Local aArea := GetArea()
PARAMTYPE 0 VAR cID AS CHARACTER
PARAMTYPE 1 VAR bPre AS BLOCK OPTIONAL DEFAULT {|| .T.}
PARAMTYPE 2 VAR bPost AS BLOCK OPTIONAL DEFAULT {|| .T.}
PARAMTYPE 3 VAR bCommit AS BLOCK
PARAMTYPE 4 VAR bCancel AS BLOCK
Tenha o hábito de proteger a entrada de seu programa. Se uma variável não precisa ser passada ou ela foi criada numa mantenção, tenha em mente que outros desenvolvedores não conhecem a mudança, portanto inicialize a variável de modo que a função tenha o comportamento anteriormente esperado. Lembre-se você dificilmente terá condições de alterar todos os lugares onde seu programa foi utilizado.
Tenha o hábito de posicionar as WorkAreas utilizadas pelo seu programa. Existem funções que garantem o posicionamento da WorkAreasem prejudicar o desempenho, tais como MsSeek e MsGoto.
Lembre-se seu programa deve ser uma caixa preta. Quem o utiliza precisa apenas da documentação para consumi-lo, não do código-fonte.
Corpo do programa
É nesta área que se encontram as linhas de código do programa. É onde se realiza a tarefa necessária através da organização lógica destas linhas de comando. Espera-se que as linhas de comando estejam organizadas de tal modo que no final desta área o resultado esperado seja obtido, seja ele armazenado em um arquivo ou em variáveis de memória, pronto para ser exibido ao usuário através de um relatório ou na tela.
Para fornecer legibilidade à área do corpo do programa é necessário utilizar comentários e regras de formatação.
Os comentários devem ser utilizados para explicar cada bloco das linhas de código do corpo do programa. Não é necessário exemplificar trechos óbvios, porém faz-se necessário exemplificar a linha de pensamento utilizada naquele trecho, bem como a fonte da regra de negócio. Exemplo:
//----------------------------------------------------------------------
// Calculo do ICMS de Goiás, Decreto 23.756 de 12/12/1970.
//----------------------------------------------------------------------
Ao colocar um comentário, tenha em mente o que você precisará saber para fazer a manutenção daqui há 10 anos. Algo óbvio hoje pode não ser daqui há 10 anos.
O tamanho da linha do código-fonte ideal é aquele que não necessita de ser deslocado para ser visualizado. Uma linha de 130 caracteres é ideal em muitas resoluções de monitores.
Quando houver necessidade de dividir um trecho de código formado por uma sentença lógica, prefira dividir as sentenças completas para facilitar a visualização dos fechamentos. Exemplo:
Prefira: If ( !Empty(cNome) .And.;
!Empty(cEnd) .And.;
!Empty(cTel) .Or. !Empty(cFax)) .And.;
nValor != 0 )
GravaDados(cNome,cEnd,cTel,cFax,cEmail)
Endif
Em vez de: If ( !Empty(cNome) .And. !Empty(cEnd) .And. (!Empty(cTel) .Or.;
!Empty(cFax)) .And. nValor != 0 )
GravaDados(cNome,cEnd,cTel,cFax,cEmail)
Endif
Embora o AdvPl suporte a abreviação de comandos para quatro letras (“Replace” pode ser escrito como “Repl”) é expressamente proibida a utilização dessa funcionalidade. Isto apenas torna o código mais difícil de ser lido e não torna a compilação mais rápida ou simples.
A identação do código é obrigatória, pois torna o código muito mais legível. A utilização da identação seguindo as estruturas de controle de fluxo (while, if, case, etc) torna a compreensão do código muito mais fácil. Para identar o fonte utilize a tecla ">".
Uma convenção amplamente utilizada é a de capitular as palavras chaves, funções, variáveis e campos utilizando uma combinação de caracteres em maiúsculo e minúsculo, visando facilitar a leitura do código fonte. Exemplo:
dbSelectArea, MsSeek, dbGoto, MsGoto, FWUserAccount, FWUserAuth, etc...
Por fim, tenha o hábito de utilizar caracteres maiúsculos para constantes, defines e campos de tabelas e/ou variáveis de memória destes campos. Exemplo: SC6->C6_QTDVEN, M->C5_CLIENTE, SD2->D2_TOTAL, SF2->F2_TIPO, M->C2_FORNECE.
Área de Encerramento
É nesta área onde as finalizações são efetuadas e onde o resultado da execução do programa é utilizado. Pode-se exibir o resultado armazenado em uma variável ou em um arquivo ou simplesmente finalizar, caso a tarefa já tenha sido toda completada no corpo do programa.
As WorkAreas modificadas devem ser protegidas de modo a manter o estado inicial quanto a posicionamento ( RecNo ), Ordenação ( IndexOrd() e área default selecionada (DbSelectArea). Utilize o par de funções GetArea e RestArea para isto.
Os arquivos temporários abertos devem ser fechados e deletados. Arquivos desnecessários consomem os recursos do ambiente, deixando todo o sistema mais lento. Reveja o bloco de código e verifique se todos as query´s foram fechadas, se os arquivos binários e ISAM foram fechados e apagados .
Lembre-se seu código-fonte é uma caixa-preta!
Visão Geral
Import HTML Content
Conteúdo das Ferramentas
Tarefas