Nombres SIGNIFICATIVOS
Significativo: que da a entender
o conocer con precisión.
Nombres que revelen intención
El nombre de una variable, función,
parámetro o clase debería aclarar:
- ¿por qué existe?
- ¿qué hace?
- ¿cómo se usa?
Dedica el tiempo necesario a escoger el nombre.
int d; //dias transcurridos
//VS
int diasTranscurridos;
int diasDesdeCreacion;
int diasDesdeModificacion;
Evita desinformación
Se debe prevenir el uso de
nomenclatura que introduzca confusión.
cuentasList; //Si no es de tipo List....
XYZControllerConManejoEficienteDeStrings;
XYZControllerConAlmacenamientoEficienteDeStrings;
haz distinciones que aporten valor
public void copiarObjeto(Clase1 o1, Clase1, o2);
//vs
public void copiarObjeto(Clase1 origen, Clase1 destino);
pronunciable
Si no lo puedes pronunciar,
no puedes debatir sobre el
sin quedar como un idiota.
- Por favor, revisa que el servicio PHCTB2
informa correctamente el IUCC en el OGEST.
- ¿El servicio PHCPB2?....
nombres buscables
De lo más usado:
Ctrl+F: buscar en fichero
Ctrl+Shift+F: buscar en ficheros
(o el acceso rápido que tenga tu IDE)
Aumenta tu productividad con buenos nombres
evita encodings
¿No tenemos lenguajes con tipado estático?
- iContador
- arrNums
- bOcupado
u32Identificador
(Y para tipado dinámico, apoyate en TDD)
evita mapas mentales
Los lectores no tienen que tener que traducir
tus nombres a otros que entiendan.
La claridad es fundamental.
nombres de clases
- Deberían ser nombres y no verbos
- Evitar palabras ambiguas como "Manager",
"Gestor", "Procesador", "Controller", "Data",
"Info"
nombres de métodos
- Deben ser un verbo
- Y en castellano además es bueno
que sea imperativo
- En el caso de constructores, mejor
que sobrecargar es usar métodos estáticos
de factoría.
Contexto
aporta contexto si es necesario
pero
evitar contexto gratuito
Evita cosas como:
- Reusar el nombre de una clase dentro
de una propiedad: Contacto.ContactoNombre
- Prefijar las clases con el nombre de una aplicación,
para eso están los namespaces/packages.
una palabra por concepto
- Consistencia en toda la aplicación.
- Evita que una palabra tenga varios significados.
- Evita usar varias palabras para lo mismo.
palabras del ámbito de negocio
- Utiliza la semántica del ámbito de negocio
de la aplicación: ¿que palabras usa tu cliente?
- Las términos usados deben coincidir
con la forma en que los usuarios verbalizan
los problemas.
Funciones
Cada vez más importantes: FP
(Functional programming o programación funcional)
pequeñas
Primera regla: Tienen que ser muy pequeñas.
Segunda regla: Deben ser aún más pequeñas.
Tercera regla: Todavía es muy grande.
hacen una cosa
Una función:
hace solo UNA cosa,
y la hace BIEN
y no hace nada más.
un nivel de abstracción
Una función no debe mezclar
niveles de abstracción.
Por ejemplo, no debe hacer invocaciones
a funciones de alto nivel y cosas técnicas
a la vez.
String documento = generaDocumento();
documento.append("Generado automaticamente por el sistema.")
SWITCH
Suficiente entidad para ser la única
responsabilidad de una función.
public Importe calculaPaga(Empleado e) throws TipoEmpleadoInvalidoException {
switch(e.type) {
case COMISIONISTA:
return calculaComisiones(e);
case ASALARIADO:
return calculaSalario(e);
case FREELANCE:
return calculaPagoPorHoras(e);
default:
throw new TipoEmpleadoInvalidoException(e);
}
}
Muchas alternativas
var calculadoras = {};
calculadoras.COMISIONISTA = calculaComisiones();
calculadoras.ASALARIADO = calculaSalario();
calculadoras.FREELANCE = calculaPagoPorHoras();
function calculaPaga(empleado) {
return calculadoras[empleado.type](empleado);
}
nombres descriptivos
- Sin miedo a los nombres largos.
- Mejor un nombre largo y claro
que corto y enigmático.
- Mejor un nombre largo y claro
que un comentario.
- Utiliza un estilo que facilite la lectura.
- Sin pasarse:
miObj.elMetodoConNombreTanLargoQueAlFinalNoTeAcuerdasDelPrincipio()
ARGUMENTOS
Número de parámetros:
- Ninguno: bueno..
- Uno (función monádica): BIEN, fácil de concatenar.
- Dos (función diádica): humm... ok
- Tres (función triádica): hummmmmm..... ¿estas seguo?
- Más de tres: Refactoriza
Flags:
- ¿Se entienden?
.render(true)
vs
.renderSuite()
.renderSingleTest()
SIN EFECTOS SECUNDARIOS
- Mejor programación funcional.
- Los efectos secundarios
generan acoplamientos.
- Si no queda más remedio, que quede
explicitado:
.compruebaClaveEIniciaSesion()
CONSULTA U ORDEN
Las funciones deberían:
- hacer algo
- consultar algo
- pero no ambas cosas
(aunque a veces se resuelve bien, jQuery)
objetos y estructuras de datos
Hay un motivo para la existencia de variables privadas:
no queremos que nadie dependan de ellas.
¿Por qué añadir getters y setters a todas ellas?
abstracciones correctas
Hablemos de un punto:
public class Punto {
public double x;
public double y;
}
public interface Punto {
public double getX();
public double getY();
public setCartesianas(double x, double y);
public double getR();
public double getTheta();
public setPolares(double r, double theta);
}
estructuras u objetos
- En lenguaje procedimental es más fácil
añadir funcionalidad sin afectar a las
estructuras. En OO, es fácil añadir nuevas
clases sin cambiar las funciones.
- En lenguaje procedimental es difícil añadir
estructuras, pues afecta a todas las funciones.
En OO, es más difícil añadir funciones porque
todas las clases se ven afectadas.
Ley de demeter
Un objeto no debe conocer nada
acerca de las interioridades de los objetos
que maneja.
Queremos evitar los accidentes de trenes:
ctx.getSession(true).getStorage().get("dato").value
gestión de errores
¿Códigos de error devueltos
por una función? No, por favor.
Programación síncrona: excepciones.
Programación asíncrona: objetos de error.
- Patrón de continuación: primer argumento
- Promesas o FRP: función controladora de error
Excepciones ¿chequeadas o no?
Unchecked salvo que sea
imprescindible lo contrario.
definición y CONTEXTO
Las excepciones tienen que definirse
en función de las necesidades de los usuarios.
Tienen que proporcionar el contexto suficiente
para entender su generación.
NULL
No devuelvas null
(En algunos lenguajes te puedes proteger de
NullPointerExceptions: scala, coffescript,...)
NO PASES NULLs
(En Java, intenta poner todo con final y te ahorrarás muchos NullPointerException)
Para recordar
¡ACRÓNIMOS y frasecitas!
(En inglés...)
SRP
Single Responsibility Principle
Todo objeto tiene una única responsabilidad
completamente encapsulada
KISS
Keep it simple, stupid!
Keep it simple and stupid.
Keep it short and simple.
Keep it simple and straightforward.
Vamos, simplicidad.
YAGNI
You ain't gonna need it.
Cuidado con los "por si acaso".
Implementa la funcionalidad cuando
la necesites.
DRY and DIE
Don't repeat yourself.
Duplication is evil.
Toda pieza de conocimiento debe
tener una representación única,
inequívoca y autoritaria.
ley de demeter
No hables con extraños.
POLS
Principle of Least Suprise.
Las cosas deberían comportarse
como se espera que se comporten.
Principio de hollywood
No nos llames, ya te llamamos nosotros.
POGE
Principle of Good Enough
Favorece diseños sencillos y rápidos (pero
potencialmente extensibles) sobre diseños elaborados.
Implementa lo que necesites,
no lo que creas que vas a necesitar.
Ley de Brook
Nueve mujeres no hacen un bebé en un mes.