anonymousLog in-Register  
Groups

Boas práticas de programação em Genexus - Português

Same page but  with a 'rename safe' link (used for external links)
Versão Original em Espanhol


As boas práticas de programação em Genexus servem para melhorar a compreensão e clareza do código, além de permitir unificar critérios entre vários programadores das empresas.

As boas práticas de programação em Genexus inicia-se baseando que o código é a melhor documentação que um sistema deva ter, por isto também é a melhor ferramenta que um programador tem para compartilhar seu trabalho aos demais programadores.

Ao Utilizar boas práticas de programação em Genexus o código da Kb obtém um valor agregado já que possui:

  • Fácil integração e reutilização;
  • Fácil compreensão por parte do programador;
  • Unificação de critérios;
  • Eliminação de zonas obscuras(ocultas) no código;
  • Fácil comunicação entre os programadores;
  • Clareza e código escrito corretamente;
  • Diminuição significativa na manutenção do Software;

As boas práticas de programação em Genexus estão compostas por regras e recomendações:

Regras

  • 01) Ao nomear atributos deve-se utilizar a nomenclatura GIK(GeneXus Incremental Knowledge Base);

  • 02) Os atributos deverão ter descrição e Help(ajuda);

     Nome: CliCod
Descrição: Código do Cliente
Help: Identificador do Cliente no sistema.


  • 03) As tabelas devem ter nomes que representem a realidade e não um nome herdado pela transação que a cria.

     Transação:  Cli2SisPro
Tabela: Clientes


  • 04) As variáveis que façam referencia a um atributo devem ser baseadas no mesmo(basead on atribute) e ter o mesmo nome do atributo, se a lógica assim permitir.

     Atributo: CliCod	- C(20)		- Código do Cliente			 
Variable: &CliCod - C(20) - Código do Cliente



  • 05) Relatório de Especificação

    Considera-se um boa prática que o Analista / Programador Genexus revisem com atenção o relatório de especificação já que este é a principal ferramenta que permite identificar erros no código.



Definição de Regras

Em ocasiões que não se define um padrão para escrever as regras, fica um código muito "complexo" , difícil de entender o comportamento desejado para um atributo em particular.

Exemplo(ERRADO, Sem padrão):

Parm(in:EmpCod, in:&Usuario, in:&CliCod, in:&Mode);

noaccept(CiuCod);

&CliSaldoAux = udp(PcalcSaldo, EmpCod, &CliCod, CliSaldo);

error('Mensaje') If Null(&Usuario);

allownulls(EmpCod, LocCod ) ;

Call(PActInfo, EmpCod, CliCod) if <cond>;

error('Mensaje') IF CliDir = nullvalue(CliDir ) and after(CliDir) ;

prompt(Wclientes, EmpCod, CliCod);

default(CliFchCrea, Now() ) ;

noaccept(EmpCod);

Call(PInfoUsr, EmpCod,&Usuario) if <cond>;

nocheck(EmpCod, LocCod);

msg('Saldo menor que cero') if CliSaldo < 0;

Refcall(Wclientes, EmpCod, CliCod);

Call(Pprocedure, EmpCod, CliCod) if <cond>;

default(CliArea, 'A' ) ;

06) Ao observarmos o código acima , nos damos conta que para buscar algo temos que recorrer até o final das regras, já que nos mostra nenhum critério a seguir. Existem muitas maneiras de definir as regras para que sejam fáceis de entender, pois vamos estabelecer um critério como boas práticas de programação.

Sugestão / Exemplo Correto:

parm( parm1, parm2, ...);

// INSTANCIAR REGISTROS (PARÂMETRO)

// DEFAULTs
default(CliFchCrea, Now() ) ;

// NOACCEPTs
noaccept(EmpCod);

// ATRIBUIÇÕES
CliEdad = Age(CliFchNac);

// INTEGRIDADE REFERENCIAL
allownulls(EmpCod, LocCod ) ;
nocheck(EmpCod, LocCod);

// VALIDAÇÃO DE CAMPOS
error("Nombre de cliente incorrecto.") if null(CliNom);

// VALIDAÇÃO DE REGISTROS
error("La fecha de vencimiento no puede ser menor a la del documento.") if DocFchVenc < DocFch;

// PROMPTs
prompt(WClientes, CliCod);

// CALL / AÇÕES
Call(PInfoUsr, EmpCod,&Usuario) if <cond>;



Recomendações

  • 07) A descrição dos objetos da KB devem ser claramente explicativos independentes do nome do mesmo;

     Nome: ModCliFinanceiro
Descripción: Modificacão dos Clientes do Financeiro

  • 08) Utilizar nomes mnemônicos para as variáveis que não correspondam a nenhum atributo do sistema.

     Se atribuir a uma variável a existência de um cliente
Forma correta: ExisteCliente
Forma Incorreta: Flag


  • 09) Utilizar nomes mnenônicos para os objetos da KB

     TrabalharComClientes


  • 10) No cabeçalho dos programas(Procs) de deve ter um quadro de comentários com uma pequena descrição do propósito do mesmo e dado úteis.

     /* 
Autor..........: Cristhián Gómez (urulinux@adinet.com.uy)
Data de criação: 26-06-2004
Parâmetros in..:
Parâmetros out.:
Alterado em ...: 27-06-2004
Comentários....: Troca o Status dos clientes logo após a confirmação e liberação pelo Financeiro.
*/


  • 11) Colocar uma linha em branco entre as definições dos eventos e as subrotinas para separar os memos e deixar mais compreensível os programas.

  • 12) Dentro dos eventos se deve começar a escrver os códigos após ter feito a identação(tabulação) corretamente, isto facilita a visualização do código.

     // Forma incorreta:
Event 'NuevoCli'
If &CliCod = &Cliente
//Codigo
Endif
EndEvent

// Forma Correta:
Event 'NuevoCli'
If &CliCod = &Cliente
//Codigo
Endif
EndEvent


  • 13) Para que os ForEach fiquem mais claros e fáceis de identificar dentro dos eventos ou no código em geral, recomenda-se que escrevam da seguinte maneira:

     // Forma Incorreta(sem identação):
Event 'NuevoCli'
For Each
where CliCod = &CliCod
//Còdigo
EndFor
EndEvent

// Forma correta(com identação):
Event 'NuevoCli'
For Each
where CliCod = &CliCod
//Còdigo
EndFor
EndEvent

  • 14) Não utilizar filtros em vários locais(Parâmetro, source e condição) ao mesmo tempo dentro de uma procedure, utilize apenas em um local "Cláusula Where" de um For each.


  • 15) Para que os filtros dos ForEach fiquem mais claros, recomenda-se ter um where para cada condição e não utilizar (AND);

     //Forma incorreta:
For Each
where CliCod = &CliCod and CliStatus = &CliStatus and CliTipo = &CliTipo
//Còdigo
EndFor

// Forma correta(Um Where para cada condição):
For Each
where CliCod = &CliCod
where CliStatus = &CliStatus
where CliTipo = &CliTipo

//Código
EndFor

/* Comentario de Demetrio Toledo.
Geralmente acostumo identificar sempre a tabela base de onde vou trabalhar com o For Each utilizando a sentença Defined By, no seguinte formato.
FOR EACH Clicod, CliStatus   // GX: CLIENTES
Where CliCod = &CliCod
Where CliStatus = &CliStatus
Where CliTipo = &CliTipo
Defined By CliEstReg
//Codigo
ENDFOR

/* Comentario de Adilson Costa.
Aproveitando o comentário anterior onde é identificada a tabela base, além de informar o nome da tabela, identifico também a sua descrição.
Utilizo também a mesma informação no fechamento do For Each para facilitar quando estamos utilizando For Each aninhados.
For Each Order Clicod, CliStatus        // Clientes -> Tabela de Clientes
Where CliCod = &CliCod
Where CliStatus = &CliStatus
Where CliTipo = &CliTipo

//Codigo

EndFor // Clientes -> Tabela de Clientes
 

  • 16) Colocar espaço depois de cada (,) nas regras, call , udp, etc. para que todos os programas fiquem mais fáceis de entender.

     // Forma incorreta:
parm(&CliCod,&UsuCod,&Tipo);
call(MiObjeto,CliCod,UsuCod,&Tipo)

// Forma correta:
parm(&CliCod, &UsuCod, &Tipo);
call(MiObjeto, CliCod, UsuCod, &Tipo)


  • 17) Evite abreviar excesivamente

Os nomes das variáveis, subrotinas, objetos, etc, devem ser o mais claro possíveis já que se alguém externo trabalhar com o código, além de entender o código em geral,
deverá estar descifrando os nomes de cada variáveis, etc.

Exemplo: Se quiser atribuir a uma variável o cliente por fornecedor
   //Forma Incorreta:
&CPForn

//Forma correta:
&ClientePorFornecedor


  • 18) Clareza no código

A clareza no código também se considera uma boa prática de programação, em muitos casos por costume dos programadores abusam do uso do "if" esquecendo que existe o
comando "Do Case". Em muitos casos isto se deve as primeiras versões do Genexus que não suportavam este comando e de costume não trocaram / modificaram a escrita do código.

  • 19) Os atributos devem estar baseados em Domínios(Domains)

Deve-se definir todos os atributos sempre que possível , sejam baseados em algum Domínio, sendo fácil adaptar-se a alterações de tipos ou larguras.


  • 20) Utilização de Patterns, quando possível.

Recomenda-se que toda aplicação web utilize Patterns, os Patterns(padrões) nos oferecem uma ferramenta ideal para criar aplicações web. Facilitam a migração do ambiente wina web e nos oferecem uma forma prática de solucionar problemas que antes demorávamos muito tempo.

  • 21) Evitar constantes no código

Usar os Enumeradores ao invés de constantes no código. Desta maneira se trocar a constante não é necessário trocar em todos os objetos que ela é utilizada.

    &Type = "CR" // Errado

&Type = BalanceType.Credit // Correto








  • 22) Manutenção das Kb's

A natureza da maioria dos projetos nos leva a crer que estamos fazendo alterações constantes no conhecimento inicial que temos armazenados em nossas Kbs. As solicitações de alteração dos clientes disparam um monte de ações que em diversas ocasiões modificam grande parte da nossa lógica inicial de negócios.

Isto faz com que existam KB's que tenham muitos objetos, atributos e tabelas que não se utilizam ou que deixaram de se utilizar por alguma alteração ou reconstrução do código. O que possibilitará que na KB exista objetos duplicados e desnecessários e a medida que uma KB cresce , cresce também os tempos de produção.

Existem tarefas que sem nos darmos conta poderemos otimizar nossas kb, realizando a manutenção do conhecimento existente em uma kb. Fazendo uma boa manutenção podemos baixar os tempos de:

    • Build All

    • Copy Model

    • Update Model

    • Generate Help

    • Publicación de Información con GXPublic

    • Respaldos

Seria bom em certas ocasiões tomarmos um tempo livre para apagar todos os objetos, atributos, domínios, butipois e tabelas que não utilizarmos. Isto diminuirá os tempos de produção e ajudará bastante que nossas KB's tenhm o conhecimento que necessita para responder as nossas necessidades.

Uma das coisas que faz com que uma KB cresça é ter modelos sem utilizar. Como recomendação seria bom eliminar todos os modelos que não se utilizem em uma KB.


  • 23) Encapsular código mediante o uso de atributos fórmula

Um aspecto muito relevante na hora de dar manutenção no software é ter as definições dos vários tipos de cálculos que se realizam sobre os dados em um local centralizado. Para isto recomendamos ter incorporado estes cálculos como atributos FÓRMULA. Neste formato nos asseguramos que quando se troca o cálculo que se quer realizar para obter uma determinada informação, se troca o atributo fórmula e isto é válido para todo o sistema.

Por último uma nomenclatura proposta para os casos em que a definição de um ATT(atributo) fórmula está baseado em um procedimento. "Exemplo: CliSdoRes = udp(P...)" o nome do procedimento deve ser igual ao nome do atributo.

No exemplo anterior ficaria "CliSdoRes = udp(PCliSdoRes...)", outra opção é colocar antes do nome da proc(procedure) o sufixo "frm", no exemplo citado anteriormente ficaria "CliSdoRes = udp(PfrmCliSdoRes).





 
Created: 9 May 2008 03:54 PM by rcoproc Last update: 10 May 2008 08:11 AMbyrcoproc