Escolar Documentos
Profissional Documentos
Cultura Documentos
O presente documento tem por objetivo estabelecer um padrão de boas práticas a serem
utilizadas pelas equipes de desenvolvimento que atuam na plataforma Protheus AdvPL. As regras
aqui listadas não são restritivas, mas buscam estabelecer uma identidade única para os fontes. A
adoção desse padrão deve naturalmente se tornar um hábito, aumentando a legibilidade dos
fontes e proporcionando mais segurança no processo de manutenção de sistemas.
Novas funções devem ser desenvolvidas considerando as boas práticas listadas, e funções já
existentes devem ser adequadas gradativamente. Entretanto não se recomenda a mudança de
trechos que não fazem parte do escopo de alteração, de forma a não comprometer a revisão
técnica do fonte nem gerar risco de inserção de novos bugs acidentalmente.
Arquivo
A extensão deve ser minúscula (exemplo: .prw , .apw )
Estilo
Tabs somente para indentação, não para separação
A tabulação deve ser utilizada somente à esquerda, antes de iniciar a linha e nunca no meio
da linha. O motivo é que quando o arquivo for aberto em diferentes editores (TDS, VSCode,
Sublime, etc.), a formatação será respeitada
Iniciar por:
n-numérico
c-char/string
d-data
l-logic/boolean
a-array/matriz
o-objetos
b-bloco de código
x-indefinido
Evite nomes de variáveis como nX ou nY (exceto para índices). Seja mais descritivo
Prefira declarar variáveis agrupando-as logicamente por tipo ou utilização, separando por
linhas
É redundância inicializar variáveis com Nil , exceto variáveis públicas, que por sua vez não são
comuns - no geral se considera uma prática ruim por poluir o escopo global
Ao terminar uma instrução For , prefira Next <variable> ao invés de somente Next
Use as variáveis com nomes iguais em tamanho e caixa (não faça thisIsMyVari e
THISISMYVARI )
Nomes de funções e métodos sem notação húngara devem usar UpperCamelCase (exemplo:
RetSqlName )
Diretivas do pré-processador (#define < include >) devem referenciar a include com a mesma
capitulação do arquivo físico, preferencialmente letras minúsculas.
É uma boa prática que evita conflitos de case sensitive em processos de compilação no Linux,
por exemplo.
Evite ultrapassar 120 colunas horizontalmente. Quebre o código com ; quando necessário
Function Test()
If Something
...
EndIf
For nI := 1 To 10
For nZ := 1 To 10
...
Next nZ
Next nI
Return
Separar funções, pulando uma linha após o return, antes de iniciar um novo bloco
Ferramentas de diff se perdem sem linha final e alguns editores já salvam por padrão uma
linha extra. Alguns compiladores não entendem o fim de arquivo (não é o caso do AdvPL),
por isso é uma boa prática em programação.
Aspas simples facilitam a leitura do código e permitem, por padrão, o uso de aspas duplas
nas strings (ex: cString := 'Verifique o campo "quantidade" na tela')
Funções não devem receber mais que 6 parâmetros (dessa forma se mantém uma função
mais coesa, com um objetivo específico)
Não desenvolva funções de alto acoplamento, quer dizer, funções que precisam estar
acopladas à outras funções ou variáveis para funcionar (como o caso de funções que utilizam
variáveis private declaradas em outro fonte)
A função de If em linha deve ser utilizada com os dois I's em maiúsculo: IIf
Use If somente para statement (If .. Else .. EndIf) e IIf para expressão (x:= IIf(lVar,10,20))
Statements não atribuem valor, por exemplo If (lVar) enquanto expressão atribui, por
exemplo x := If(lVar, 10, 20) . O AdvPL permite a ambiguidade de se usar If e IIf para
expressões. Nesse caso utilize sempre IIf , pois se usar If o compilador irá buscar pelo
EndIf , o que poderia gerar erro em outras linguagens.
Use != ao invés de <>
Espaçamento
Deve haver 1 espaço entre os argumentos de função, blocos e arrays (exemplo: RetSqlName(
'STJ' ) )
Deve haver espaço entre parâmetros de funções (use Call( 1, 2, 3 ) e não Call(1,2,3) )
O Return pode ficar alinhado à esquerda (mesmo alinhamento de Function), mesmo não
sendo um terminador
Prefira comentários em // para quando uma linha e /**/ para trechos de código ou
comentário de parâmetros (ex: function(10 /*nAltura*/ ,20 /*nLargura*/ ))
Redundância
Substitua If dentro de If por .And.
Funcionamento
Lembre-se de, ao criar uma tabela temporária, fechá-la com dbCloseArea e para casos em
que se usa FWTemporaryTable, usar o método delete
Quando deslocar para outro registro utilizando dbSkip , garanta estar posicionado na tabela
desejada, caso contrário utilize TABLE->( dbSkip() ) ou então utilize dbSelectArea( TABLE )
antes do dbSkip()
Funções
Toda função deve ter um cabeçalho de documentação baseado no modelo Protheus.doc, e o
autor genérico (como "J2A Consultoria") não deve ser utilizado
São consideradas funções genéricas aquelas que se aplicam a qualquer módulo, normalmente
sem tratar de conceitos e regra de negócio. Devem ser criadas em fontes genéricos como
NGUtil e preferencialmente começar pelos caracteres NG
São consideradas funções genéricas do módulo aquelas que atendem regras mais genéricas
de algum módulo, sendo utilizadas em um grupo de rotinas. Devem ser criadas em fontes do
módulo como MNTUtil ou MDTUtil e preferencialmente começar pelos caracteres do módulo,
ex: MNT ou MDT
São consideradas funções de rotina aquelas que atendem regras específicas de alguma rotina,
mas que também podem ser chamadas externamente. Devem ser criadas no fonte que a
utiliza e preferencialmente começar pelos caracteres da própria rotina, como MNTA080Cad() .
Evitar também reduzir o identificador do fonte para MNA080 ou MNT080
São consideras funções estáticas aquelas que são utilizadas apenas por um determinado
fonte, sem chamada externa por outros fontes. Devem ser criadas no fonte que a utiliza e
preferencialmente iniciando pelo caracter f como fCalcHora()
Referências
AdvPL Coding Standards - https://github.com/haskellcamargo/advpl-coding-standards by
@haskellcamargo