Gracias a Daniel Monza: Buenas prácticas con genexus
# Sincrum - Guia de estilo para el desarrollo en GeneXus
Definición de nombres
- 1.1 Se debe ser descriptivo con los nombres.
Se intenta que el nombre sea autodescriptivo.
// mal
Proc: CliCre
// bien
Proc: ClienteCrear
```
- 1.2 Utilizar PascalCase al nombrar objetos, atributos y variables.
// mal
clientecrear
// bien
ClienteCrear
```
- 1.3 No utilizar underscore al inicio o final en ningún tipo de objeto, atributo o variable.
Esto puede hacer suponer a un programador proveniente de otros lenguajes que tiene algún significado de privacidad.
// mal
&_CliNom = "John Doe"
&CliNom_ = "John Doe"
Proc: _ClienteCrear
// bien
&CliNom = "John Doe"
```
- 1.4 Nombrar los dominios enumerados comenzando con la entidad en singular y siguiendo con el enumerado en plural sin abreviar estos.
// mal
DocumentoTipo
DocumentosTipos
DocTipos
// bien
DocumentoTipos (Venta,Compra,etc)
DocumentoModos (Credito, Débito)
```
- 1.5 Nombrar procedimientos relacionados mediante Entidad + Atributo(depende el caso) + Complemento + Acción.
Esto permite agrupar los objetos de la misma entidad en la selección de objetos entre otros.
// mal
CreCli
UpsertCliente
FechaCliente
// bien
ClienteUpsert
ClienteEliminar
ClienteFechaModificadoGet
ClienteFechaModificadoSet
DocumentoRecalculo
```
- 1.6 Utilizar [nomenclatura GIK](http://wiki.genexus.com/commwiki/servlet/wiki?1872,GIK) para nombrar atributos. En lo posible, intentar utilizar los nombres completos en lugar de 3 caracteres.
> Estandard desde los inicios de GeneXus.
// mal
CreCliFch
FechaCreadoCliente
// bien
CliFchCre
// mejor
ClienteFechaCreado
```
- 1.7 Las transacciones deben tener el nombre de la entidad en plural.
Las transacciones definen el nombre de las tablas en GeneXus. Se defien en plural ya que estas contienen N registros de la misma entidad.
// mal
Trn:Articulo
Trn:Cliente
// bien
Trn:Clientes
Trn:Articulos
```
- 2.1 Siempre que se pueda, utilizar tabuladores en lugar de "espacios". De esta forma, cada uno puede visializar la cantidad de espacioes que prefiera, ya que se configura en GeneXus. En los casos que no se pueda, y para definir un criterio, se utiliza una identación/tabulación de 3 espacios.
Esto es porque la mayoría de los comandos queda mas legibles con esta tabulación.
// mal
if &DocumentoTipo = DocumentoTipos.Venta
msg("Venta")
endif
// mal
if &DocumentoTipo = DocumentoTipos.Venta
msg("Venta")
endif
// mal
if &DocumentoTipo = DocumentoTipos.Venta
msg("Venta")
endif
// bien
if &DocumentoTipo = DocumentoTipos.Venta
msg("Venta")
endif
```
- 2.2 Se deben identar las condiciónes y comandos dentro de un for each.
// mal
for each
where DocumentoTipo = DocumentoTipos.Venta
...
endfor
// mal
for each
defined by ClienteNombre
...
endfor
// bien
for each
where DocumentoTipo = DocumentoTipos.Venta
...
endfor
```
- 2.3 Dejar un espacio antes de cada parámetro.
Hace a la sentencia más sencilla de leer.
// mal
parm(in:PaiId,out:&PaiNom);
// bien
parm( in:PaiId, out:&PaiNom);
// mal
&Fecha = ymdtod(2017,01,01)
// bien
&Fecha = ymdtod( 2017, 01, 01)
```
Dominios enumerados
- 3.1Evitar la utilización de textos/números fijos cuando pueden existir multiples valores.
Simplificar la lectura y no necesitar recordar el texto específico de cada opción.
// mal
if &HttpResponse = "GET"
// bien
if &HttpResponse = HttpMethods.Get
```
Structured Data Types
- 4.1 Utilizar New() en la creación de SDT en lugar de Clone().
Queda claro que se está trabajando con un nuevo item.
// &Cliente SDT:Cliente
// &Clientes lista de SDT:Cliente
// mal
for each Clientes
&Cliente.CliNom = CliNom
&Clientes.Add( &Cliente.Clone() )
endfor
// bien
for each Clientes
&Cliente = new()
&Cliente.CliNom = CliNom
&Clientes.Add( &Cliente )
endfor
```
- 4.1 Desde que GeneXus permite definir variables como listas, evitar crear SDT del tipo lista.
Al definir la variable del item particular, se lo marca como lista.
// mal
SDT:Clientes : Lista
ClienteItem
CliNom
// bien
SDT:Cliente
CliNom
```
Strings
- 5.1Utilizar [format](http://wiki.genexus.com/commwiki/servlet/wiki?8406,Format%20function) para desplegar mensajes conteniendo datos.
Si la aplicación se va a traducir en diferentes lenguajes no hay que re-programar los mensajes.
// mal
&Msg = "El cliente Nro." + &CliId.ToString() + " se llama " + &CliNom
// bien
&Msg = format( "El cliente Nro. %1 se llama %2", &CliId.ToString(), &CliNom)
```
- 5.2 Utilizar !"" para strings que no deben ser traducidos.
Un traductor puede modificar constantes o códigos específicos del sistema y pueden afectar el funcionamiento, por ejemplo parámetros.
// mal
&ParVal = ParamGet( "GLOBAL ENCRYPT KEY")
// bien
&ParVal = ParamGet( !"GLOBAL ENCRYPT KEY")
```
Comentarios
- 6.1 Utilizar `/** ... */` para comentarios multi-línea.
// mal
// CrearCliente crea una nuevo cliente
// según las variables:
// &CliNom
// &CliDir
sub 'CrearCliente'
// ...
endsub
// bien
/**
* CrearCliente crea una nuevo cliente
* según las variables:
* &CliNom
* &CliDir
*/
sub 'CrearCliente'
// ...
endsub
```
- 6.2 Utilizar `//` para comentarios de una sola línea. Estos comentarios deben estar una línea antes del sujeto a comentar. Dejar una línea en blanco antes del comentarios a no ser que seal la pimer línea del bloque.
// mal
&CliNom = "John Doe" // Se asigna el nombre a la variable
// bien
// Se asigna el nombre a la variable
&CliNom = "John Doe"
// mal
sub 'CrearCliente'
msg( "Creando cliente", status )
// Se crea el cliente
&ClienteBC = new()
&ClienteBC.CliNom = "John Doe"
&ClienteBC.Save()
endsub
// bien
sub 'CrearCliente'
msg( "Creando cliente", status )
// Se crea el cliente
&ClienteBC = new()
&ClienteBC.CliNom = "John Doe"
&ClienteBC.Save()
endsub
// también está bien
sub 'CrearCliente'
// Se crea el cliente
&ClienteBC = new()
&ClienteBC.CliNom = "John Doe"
&ClienteBC.Save()
endsub
```
- 6.3 Comenzar todos los comentarios con un espacio para que sean sencillos de leer.
// mal
//Está activo
&IsActive = true
// bien
// Está activo
&IsActive = true
// mal
/**
*Se obtiene el nombre de la empresa
*para luego desplegarlo
*/
&EmpNom = EmpresaNombreGet( &EmpId)
// bien
/**
* Se obtiene el nombre de la empresa
* para luego desplegarlo
*/
&EmpNom = EmpresaNombreGet( &EmpId)
```
- 6.4 Agregar pefijos en los comentarios con `FIXME` o `TODO` ayudan a otros desarrolladores a entender rapidamente si se está ante un posible problema que necesita ser revisado o si se está sugiriendo una solución a un problema existente. Estos son diferentes a los comentarios regulares porque conllevan a acciones. Estas acciones son `FIXME: -- necesita resolverse` or `TODO: -- necesita implementarse`.
- 6.5 Usar `// FIXME:` para marcar problemas.
// FIXME: Revisar cuando &Divisor es 0 &Total = &Dividendo / &Divisor
```
- 6.6 Usar `// TODO:` para marcar implementaciones a realizar.
// TODO: Implementar la subrutina
sub "CrearCliente"
endsub
```
Comandos y funciones
- 7.1 Utilizar minúsculas al nombrar comandos.
Esto optimiza el desarrollo ya que los comandos y funciones provistas por el lenguaje se utilizan tan frecuentemente y no es necesario especificarlos en PascalCase.
// mal
For Each
Where CliCod = &CliCod
Msg(CliNom)
EndFor
// bien
for each
where CliCod = &CliCod
msg(CliNom)
endfor
// mal
&Fecha = YmdToD( 2017, 01, 01)
// bien
&Fecha = ymdtod( 2017, 01, 01)
```
- 7.2 Utilizar [do case](http://wiki.genexus.com/commwiki/servlet/wiki?31605,Do%20Case%20command) siempre que se pueda a fín de sustituir [if](http://wiki.genexus.com/commwiki/servlet/wiki?8608,If+Command,) anidados. Dejar un espacio entre cada bloque de case.
// mal
if &DocTipo = DocumentoTipos.Venta
...
else
if &DocTipo = DocumentoTipos.Compra
...
endif
endif
// también mal
do case
case &DocTipo = DocumentoTipos.Venta
...
case &DocTipo = DocumentoTipos.Compra
...
endcase
// bien
do case
case &DocTipo = DocumentoTipos.Venta
...
case &DocTipo = DocumentoTipos.Compra
...
otherwise
...
endcase
```
Parámetros
- 8.1 Utilizar SDT en lugar de multiples parámetros.
La lectura queda confusa y cuando se modifican los parámetros hay que revisar todos los llamadores. Esto algunas veces no es posible, por ejemplo en webpanels.
// mal
parm( in:&CliNom, in:&CliApe, in:&CliTel, in:&CliDir, in:&CliDOB)
// bien
parm( in:&sdtCliente )
```
Recursos
**Lectura interesante**
- [GeneXus Wiki](http://wiki.genexus.com/) - GeneXus
Empresas que utilizan esta guia
Esta es una lista de las empresas que están utilizando esta guia de desarrollo. This is a list of organizations that are using this style guide. Haganos saber si su empresa utiliza esta guia o un fork de la misma y lo agregaremos.
- Sincrum (http://sincrum.com)
Colaboradores
- Son bienvenidos a colaborar.
Licencia
Documento Original creado por Daniel Monza bajo licencia MIT](LICENSE)
basado en [la guia de Javascript de AirBNB](http://airbnb.io/javascript/)