FANDOM


Esta parte do documento foi elaborada com o objetivo de melhorar a padronização entre todos os envolvidos no desenvolvimento de soluções na plataforma Inteq e que utilizem as linguagens JavaScript ou Delphi. Ele visa ser um comum acordo entre as pessoas envolvidas, tendo como metas melhorar a qualidade, clareza e objetividade dos códigos fontes criados. O ideal em nosso ambiente de trabalho é que cada desenvolvedor sinta-se em "casa" ao ler códigos escritos por outros desenvolvedores, facilitando a troca de conhecimentos e experiências quando as mesmas se fazem necessárias.

Para chegar a este ideal, devemos nos focar em criar códigos auto-explicativos, objetivos e bem organizados, que não necessitem de documentação externa ou explicações pessoais. O código fonte sempre deve ser auto-sustentável e impessoal, garantindo a continuidade da solução, mesmo na ausência de seus autores. Qualquer documentação necessária deve se encontrar dentro do próprio código fonte através de comentários ou de documentação de uso. Esta última deve ser criada através de um padrão descrito mais adiante.


Nomeação

Os nomes de variáveis, funções e classes devem indicar exatamente sua finalidade. Não deve haver dúvidas ao leitor do código sobre o que está sendo armazenado na variável ou sobre o que será executado/retornado numa função. Evite utilizar abreviações principalmente as que não são de domínio público. Não devemos usar prefixos que indiquem tipos de dados como: gridNome, grdNome, actBuscar, arLinhas, dataEmissao ou valorTotal. A utilização de prefixos é óbvia para o desenvolvedor que escreveu o código, mas pode não ser para quem está lendo. Prefixos aumentam a quantidade de conhecimento que um desenvolvedor deve possuir para nomear uma simples variável. Passa a ser necessário ter conhecimento do prefixo adequado para o tipo do dado que uma variável irá armazenar, tarefa complicada quando existem vários tipos de dados. O prefixo também não é essencial para a identificação do registro, pois um bom nome e o contexto de uma variável indicam o tipo do seu conteúdo. O exemplo abaixo é uma brincadeira com a “Notação Húngara‿ que demonstra que não usamos prefixos em nossa linguagem natural, nem por isso deixamos de entender o significado das frases:

  prepBut nI vrbLike adjHungarian! qWhat's artThe adjBig nProblem?

Devemos levar em conta as exceções, onde o prefixo torna o código mais legível. O exemplo abaixo faz uma boa utilização de prefixos para determinar as informações de um acontecimento:

 var dataPagamento  = ds.emissao
 var valorPagamento = ds.valor


Nomes de Variáveis

Nomes de variáveis ou propriedades devem representar algo. Devem iniciar sempre com letras minúsculas, prosseguindo assim, exceto no início de cada palavra cuja primeira letra deverá ser maiúscula.

ERRADO

  var Hoje = new Date()
  

CORRETO

  var hoje = new Date()
  


Nomes de Funções

Nomes de funções ou métodos devem representar uma ação. Devem iniciar com letras minúsculas. As demais letras deverão ser minúsculas, exceto no início de cada palavra. Ex:

ERRADO

  function custoContabil() {
  }
  

CORRETO

  function pegaCustoContabil() {
  }


Nomes de Classes

Nomes de classes devem representar tipos. Devem iniciar com letra maiúscula. As demais letras serão minúsculas, exceto no início de cada palavra. Ex:

ERRADO

  function objetoOperaçãoEntrega() {
     this.propriedade = 'Teste'
  }

CORRETO

  function OperacaoEntrega() {
     this.propriedade = 'Teste'
  }


Caracteres Especiais

Não devem ser utilizados caracteres especiais ou acentos em nomes de variáveis, funções ou classes.


Nomes com Siglas

Devem ser consideradas como uma palavra dentro de um nome. Ex:

ERRADO

  var aliquotaICMS = 17
  function pegaBaseDeCalculoIPI() {
  }

CORRETO

  var aliquotaIcms = 17
  function pegaBaseDeCalculoIpi() {
  }


Nomes de Campos

Nomes de campos devem ser escritos seguindo a mesma padronização utilizada na definição dos mesmos, exceto quando forem acessados como propriedades de um dataSet. Neste caso devem ser escritos todas em minúsculo. Por razões históricas, todos os campos do sistema de ERP são definidos em maiúsculas e todos os campos de infra-estrutura são definidos usando a mesma notação de propriedades, sempre prefixadas com um i.

ERRADO

  var chave = connetion.get( session.userKey, 'CCustRes' ) 
  var ds = connection.getDataSet( "Select e.chave From ENTIDADE e Where e.Codigo = 'Empresa Licenciada'") 
  var ds = connection.getDataSet( "Select INAME From IGROUPUSER Where IKEY = 1234") 
  ds.CHAVE = connection.createKey() 
  ds.cCustRes = session.userKey.cCustRes 

CORRETO

  var chave = connetion.get( session.userKey, 'CCUSTRES' ) 
  var ds = connection.getDataSet("select e.CHAVE from ENTIDADE e where e.CODIGO = 'Empresa Licenciada'") 
  var ds = connection.getDataSet("select iName from iGroupUser where iKey = 1234") 
  ds.chave = connection.createKey() 
  ds.ccustres = session.userKey.ccustres


Nomes de Tabelas

Nomes de tabelas de infra-estrutura sempre devem ser escritos seguindo a mesma notação de propriedades. Nomes de tabelas do ERP devem ser escritos todos em maiúsculo, exceto quando forem usados como variáveis e/ou propriedades. Neste caso devem ser escritos todos em minúsculo.

ERRADO

  var Entidade = connection.cloneLocalCache( 'Entidade' ) 
  var RECURSO = connection.getDataSet("Select r.CHAVE From Recurso r Where r.CODIGO = 'Parafuso'") 
  var igroupuser = connection.cloneLocalCache( 'IGROUPUSER' ) 

CORRETO

  var entidade = connection.cloneLocalCache( 'ENTIDADE' ) 
  var recurso = connection.getDataSet("select r.CHAVE from RECURSO r where r.CODIGO = 'Parafuso'")
  var iGroupUser = connection.cloneLocalCache( 'iGroupUser') 


Uso de variáveis de escopo local

O operador var sempre deve ser utilizado para definir variáveis locais. A existência do var, torna desnecessário o uso do prefixo v em nomes de variáveis, pois o leitor do código sabe que a variável está sendo declarada localmente. Somente utilize um prefixo para variáveis locais caso seja necessário diferenciá-las de variáveis de um escopo maior.

Variáveis locais para controle de interações de loops podem ser abreviadas, sendo desejável o uso do nome i como preferencial. Outras variáveis de escopo local podem sofrer abreviações padrão como: s para string, ar para um array e ds para um dataset. Procure não usar nenhuma outra abreviação além destas.

ERRADO

  vTeste = 200 
  function getPedido( vChaveCriacao ){ 
  } 
  for ( i = 0; i < 100; i++ ){ 
  } 

CORRETO

  var teste = 200 
  function getPedido( chaveCriacao ){ 
  } 
  for ( var i = 0; i < 100; i++ ){ 
  } 


Evite códigos redundantes

ERRADO

  if ( valor > 200 && data < hoje ){ 
     resultado = true 
  } else { 
     resultado = false 
  } 
  if ( resultado == true ){ 
  } 

CORRETO

  resultado = valor > 200 && data < hoje 
  if ( resultado ){ 
  } 


Não duplique código

Detecte a necessidade de criação de uma função ou classe para eliminar o código repetido. Tenha em mente que quanto menor o código, mais fácil será sua a compreensão e manutenção. Somente quebre esta regra por motivos fortes de perfomance ou clareza.

ERRADO

  var recurso = connection.cloneLocalCache( 'RECURSO' ) 
  recurso.first() 
  while ( !recurso.eof ){ 
     if ( recurso.nome ==  ){ 
        recurso.del() 
     } else { 
        recurso.next() 
     } 
  } 
  var entidade = connection.cloneLocalCache( 'ENTIDADE' ) 
  entidade.first() 
  while ( !entidade.eof ){ 
     if ( entidade.nome ==  ){ 
        entidade.del() 
     } else { 
        entidade.next() 
     } 
  } 

CORRETO

  function apagaRegistrosSemNome( nomeTabela ){ 
     var ds = connection.cloneLocalCache( nomeTabela ) 
     ds.first() 
     while ( !ds.eof ){ 
        if ( ds.nome ==  ){ 
           ds.del() 
        } else { 
           ds.next() 
        } 
     } 
  } 
  apagaRegistrosSemNome( 'RECURSO')
  apagaRegistrosSemNome( 'ENTIDADE')


Utilize e crie bibliotecas

Utilize e crie bibliotecas para garantir uma máxima reutilização de código fonte. Caso as classes e funções sejam realidades em um cliente, crie uma biblioteca na base do cliente com chave positiva. Caso sejam de uso geral, analise e discuta a possibilidade de se criar a biblioteca com chave negativa, tornando-a parte do sistema Inteq.

Bibliotecas de uso geral criadas com chave negativa devem possuir sua interface escrita em Inglês, exceto nos casos em que a realidade da biblioteca seja de termos exclusivamente locais. As interfaces das classes e funções criadas devem ser muito bem elaboradas e discutidas, pois serão eternizadas apartir do momento em que elas passarem a ser utilizadas.


Utilize lógica positiva em Branches

Em blocos condicionais, dê preferência em utilizar a lógica positiva, evitando o uso de operadores de negação ou diferença.

ERRADO

  if ( !ds.findKey( chaveUsuario ) ){ 
     ... 1 
  } else { 
     ... 2 
  } 
  if ( !condicao1 && ( valor1 != valor2 ) ){ 
     ... 1 
  } else { 
     ... 2 
  } 

CORRETO

  if ( ds.findKey( chaveUsuario ) ){ 
     ... 2 
  } else { 
     ... 1 
  } 
  if ( condicao1 || ( valor1 == valor2 ) ){ 
     ... 2 
  } else { 
     ... 1 
  }


Atenção a expressões de controle de Loops

Em uma condição com várias expressões dentro de um loop, as primeiras expressões da condição devem ser as que possam ser avalidas mais rapidamente e caso este não seja um fator determinável ou significativo, devem ser as que representam a maioria das situações testadas.

ERRADO

  for ( titulo.first(); !titulo.eof; titulo.next() ){ 
     if ( outroDataSet.find( titulo.chave ) && ( ds.pessoa == chavePessoa ) ){ 
     } 
  } 

CORRETO

  for ( titulo.first(); !titulo.eof; titulo.next() ){ 
     if ( ( ds.pessoa == chavePessoa ) && outroDataSet.find( titulo.chave ) ){ 
     } 
  } 


Utilize definições literais das classes nativas

Evite usar o construtor de uma classe quando a mesma permite uma definição literal.

ERRADO

  var s = new String('Teste')
  var i = new Number( 20)
  var ar1 = new Array()
  var ar2 = new Array()
  ar2.push( 10)
  ar2.push( 20)

CORRETO

  var s = 'Teste'
  var i  = 20
  var ar1 = []
  var ar2 = [ 10, 20 ]


Use identação padrão de 3 caracteres

Sempre indente os blocos de código adequadamente utilizando indentação de 3 caracteres ( padrão do editor para os comandos Tab, Ctrl+Shift+I e Ctrl+Shift+U ). Somente quebre a regra de de identação, quando um outro padrão seguido tornar o código mais legível.

ERRADO

  if ( condicao ) { t1 = 'Teste'  } else { 
    if ( condicao2 && condicao3 ){ 
    var ds = connection.cloneLocalCacheByClass(-2007890000 /* Pessoas */ ) 
     }} 

CORRETO

  if ( condicao ) { 
     t1 = 'Teste' 
  } else { 
     if ( condicao2 && condicao3 ) { 
        var ds = connection.cloneLocalCacheByClass( -2007890000 /* Pessoas */ ) 
     } 
  }



Use identação em expressões SQL

Utilize quebras de linhas e alinhamentos conforme exemplo abaixo, observando que as condições são isoladas umas das outras, e que toda vez que quebramos a string do query, fechamos na mesma linha. Com esta padronização facilitamos a leitura e manutenção da expressão SQL, permitindo a fácil visualização e manutenção das condições. A análise de erros, logs e profiler também se tornam mais simples, pois a identação utilizada é enviada para o servidor de banco de dados.

EXEMPLO

  this.ds = connection.getDataSet( "
                 select PESSOA, RECURSO, sum( QUANTIDADE) as QUANTIDADE, sum( TOTAL) as TOTAL 
                 from PEDIDO 
                 where EMISSAOMOV >= " + this.emissaoInicial.toSqlString() + "
                   and EMISSAOMOV <= " + this.emissaoFinal.toSqlString() + "
                 group by PESSOA, RECURSO
             ")


SUM(NOMECAMPO) as NOMECAMPO

Em um query, nomei o resultado de um SUM() com o nome do próprio campo que está sendo somado. Esta prática facilita a identificação da origem do somatório e permite a sugestão de nomes de campo do editor de scripts.

ERRADO

  var pedido = connection.getDataSet( "
                    select REPRESENTA, SUM(TOTAL) as SOMADOTOTAL
                    from PEDIDO 
                    where EMISSAO = ‘01/01/2004’ 
                    group by REPRESENTA
                 ")
  var x = pedido.somadototal


CORRETO

  var pedido = connection.getDataSet( "
                     select REPRESENTA, sum(TOTAL) as TOTAL
                     from PEDIDO 
                     where EMISSAO = '01/01/2004'
                     group by REPRESENTA
                    ")
  var x = pedido.total


Não obtenha informações do banco de dados que já estejam no cache local

Um dos principais recursos do sistema INTEQ é a tecnologia de cache local. Ela permite que os querys no banco de dados retornem apenas dados referentes à movimentação, pois todos os dados cadastrais já estão na estação local.

A utilização do cache local reduz significativamente o consumo de processamento do banco de dados e a utilização do meio de comunicação entre a estação e o servidor, além de permitir uma codificação mais simples e elegante.

ERRADO

  var chaveCliente = 123456
  var entidade     = connection.getDataSet("
                         select NOME
                         from ENTIDADE 
                         where CHAVE = " + chaveCliente + "
                     ")
  var nomeCliente = entidade.nome
  
  var pedido = connection.getDataSet( "
                         select p.CHAVE, p.CHCRIACAO, e.NOME, e.LOGRADOURO, e.OBSERVACAO
                         from PEDIDO p
                           left outer join ENTIDADE e on ( e.CHAVE = p.REPRESENTA)
                         where EMISSAO = '01/01/2004'
                    ")
  
  var s = pedido.nome + ',' + pedido.observacao


CORRETO

  var chaveCliente = 123456
  var nomeCliente = chaveCliente.nome
  
  var pedido = connection.getDataSet( "
                         select p.CHAVE, p.CHCRIACAO, p.REPRESENTA
                         from PEDIDO p
                         where EMISSAO = '01/01/2004'
                    ")
  
  var s = pedido.representa.nome + ',' + pedido.representa.observacao


Não faça cópias de DataSet desnecessárias

A cópia de um DataSet deve ser evitada, pois normalmente é um processo desnecessário e oneroso que pode ser substituído por uma lógica mais elaborada.

Esta orientação deve principalmente ser levada em consideração para clones do cache local, pois o método copy() copia todos os registros independente do filtro de classes utilizado. No exemplo abaixo, será feita uma cópia da tabela ENTIDADE.


ERRADO

  var ds = connection.cloneLocalCacheByClass( -2007878000 /* Disponíveis */)
  
  disponiveisFiltrados = new DataSet()
  disponiveisFiltrados.copy( ds)
  disponiveisFiltrados.first()
  while ( !disponiveisFiltrados.eof ){
     if ( disponiveisFiltrados.estabeleci == 187721 /* Estabelecimento Inteq */ ){
        disponiveisFiltrados.next()
     } else {
        disponiveisFiltrados.del()
     }
  }
  
  for ( disponiveisFiltrados.first(); !disponiveisFiltrados.eof; disponiveisFiltrados.next() ){
     // Processa informações do registro
  }

CORRETO

  var ds = connection.cloneLocalCacheByClass( -2007878000 /* Disponíveis */)
  
  ds.indexFieldNames = 'ESTABELECI'
  ds.find( 187721 /* Estabelecimento Inteq */)
  while ( !ds.eof && ds.estabeleci == 187721 /* Estabelecimento Inteq */ ){
     // Processa informações do registro
     ds.next(); IfUp()
  }

Interferência de bloqueador de anúncios detectada!


A Wikia é um site grátis que ganha dinheiro com publicidade. Nós temos uma experiência modificada para leitores usando bloqueadores de anúncios

A Wikia não é acessível se você fez outras modificações. Remova o bloqueador de anúncios personalizado para que a página carregue como esperado.

Também no FANDOM

Wiki aleatória