Aunque no lo parezca, todo debe cuidarse, incluso nuestro código. Ningún desarrollador quiere escribir código sucio o difícil de mantener, pero no es sencillo y muchas veces sin darnos cuenta nuestro proyecto se llena de código que a la larga nos será complicado de mantener. Puede deberse a muchas causas, presión por el tiempo, falta de documentación, inexperiencia de los desarrolladores… Es recomendable tomar las debidas acciones para que nuestro código sea limpio, más fácil de mantener y evitar problemas en el futuro. Afortunadamente, existe una técnica para reestructurar el código, se llama refactorización.
La refactorización es una técnica para mejorar la estructura interna del código del programa existente y mantener su comportamiento externo. Es un procedimiento paso a paso para mejorar el código que requiere tiempo y esfuerzo, pero merece la pena.
Desventajas del código sucio
Continuar escribiendo código en nuestro proyecto agregando nuevas funcionalidades sin refactorizar lo ya existente, puede provocar que ensuciemos más nuestro código duplicando funcionalidades y que hagamos nuestro proyecto difícil de mantener.
Estas son las desventajas de tener un código sucio.
- Incrementa el costo de mantenimiento del proyecto.
- Agregar nuevas funciones lleva mucho tiempo y, a veces, resulta prácticamente imposible agregarlas.
- Ralentiza la introducción de nuevas personas al proyecto.
- Contiene código duplicado.
- Complicado añadir test a nuestro proyecto.
- Hay muchas otras desventajas, pero estos problemas le cuestan mucho dinero y tiempo a la empresa.
Ventajas del código limpio
El código limpio tiene sus propias ventajas:
- No contiene código duplicado.
- Pasa los test.
- Hace que el código sea más legible y más fácil de comprender.
- Hace que el código sea más fácil de mantener y menos costoso.
Las ventajas del código limpio son muchas mas. Pero estas son las principales y que mas dinero pueden ahorrar a la larga, que al final es lo que mas le importa a una empresa. El proceso de convertir un código sucio y desordenado en un código limpio más fácil de mantener se llama proceso de refactorización.
Proceso de refactorización
La refactorización debe realizarse como una serie de pequeños cambios, cada uno de los cuales mejora ligeramente el código existente y permite que el programa continúe ejecutándose sin fallar. Después de la refactorización, el código debería volverse más limpio que antes. Si una vez refactorizando sigue sin ser correcto, entonces no tiene sentido refactorizar. Es solo una pérdida de tiempo y esfuerzo. También debemos tener en cuenta, que durante la refactorización no se añade código nuevo, si no que el existente se agrupa para eliminar el duplicado; además, una vez finalizada la refactorización, todo debería funcionar exactamente igual y los test pasar sin modificarlos.
Cuando refactorizar
La refactorización debe realizarse cuando:
- Cuando se duplica código para añadir la misma funcionalidad en diferentes partes del proyecto.
- Cuando el código duplicado es difícil de mantener y los cambios en un punto pueden requerir actualizaciones en muchos otros lugares.
- Añadiendo una característica nueva.
- La refactorización facilita el añadir nuevas funciones.
- Si al realizar una revisión de código, se detectan funcionalidades duplicadas o código repetido.
Técnicas de refactorización
1: Extracción:
Problema:
function mostrarFactura() {
$this->cabecera();
// Detalles.
print("name: " . $this->name);
print("amount " . $this->getPrice());
}
Solución:
function mostrarFactura() {
$this->cabecera();
$this->detalles($this->getPrice());
}
function detalles($price) {
print("name: " . $this->name);
print("amount " . $outstanding);
}
Si tienes código que podría agruparse en un método, añade un nuevo método que lo agrupe y reemplaza el código antiguo. Lo aísla y evita duplicidad.
2: Extrae variables:
Problema:
if (($estudiante->getPuntuacionMates() > 60) &&
($estudiante->getPuntuacionHistoria() > 60) &&
($estudiante->getPuntuacionCiencia() > 60) && $this->pass)
{
// hacer algo
}
Solución:
$puntuacionMates = $student->getPuntuacionMates() > 60;
$puntuacionHistoria = $student->getPuntuacionHistoria() > 60;
$puntuacionCiencia= $student->getPuntuacionCiencia() > 60;
$pasa= $this->pass;
if ($puntuacionMates && $puntuacionHistoria && $puntuacionCiencia&& $pasa) {
// hacer algo
}
Expresiones largas como la expuesta es un problema ya que dificulta la lectura y entendimiento del código. Esto puede solucionarse extrayendo los valores a variables.
3: Juntando código:
Problema:
function mostrar Resultado() {
return ($this->getResultado()) ? “Pass” : “Fail”;
}
function getResultado() {
return $this->puntuacionTotal > 300;
}
Solución:
function calificacion() {
return ($this->puntuacionTotal > 300) ? “Pass” : “Fail”;
}
Si, aunque no lo parezca, en algunas ocasiones se puede mejorar nuestro código juntándolo ya que elimina métodos que tal vez nunca se lleguen a usar.
4: Variables no útiles:
Problema:
$resultado = $estudiante->getResultado();
return $resultado > 60;
Solución:
return $estudiante->getResultado() > 60;
En algunas ocasiones utilizamos variables que pueden ser eliminadas y al hacerlo facilitamos la lectura de código.
5: Reemplazar arrays por objetos
Problema:
$row = [];
$row[0] = "Juanito Palotes";
$row[1] = 30;
Solución:
$estudiante= new Estudiante();
$estudiante->setName("Juanito Palotes");
$estudiante->setEdad(30);
Los array son muy cómodos de utilizar, pero la flexibilidad que proporcionan algunos lenguajes (como PHP) hacen que puedan ser muy complicados de entender o modificar. Es mejor utilizar objetos, que además nos proporcionan métodos y los tipos de datos.
6: Parametrizar métodos:
Problema:
function incrementarCincoPorciento() {
}
function incrementarDiezPorciento() {
}
Solución:
function incrementar($porcentaje){
}
Si tenemos métodos que realizan la misma tarea, pero solo cambia el valor que aplican, se pueden juntar en uno y pasando un parámetro.
7: Separar las consultas de los modificadores:
Problema:
function intereses() {
$this->cantidad = $this->principal * 10 / 100;
return $this->cantidad ;
}
Solución:
function setIntereses() {
$this->cantidad = $this->principal * 10 / 100;
}
function getIntereses() {
return $this->cantidad;
}
Si un método devuelve un valor y cambia un objeto, es mejor separar el método en dos.
Me metí en la aventura de Drupal con la versión 6, y aquí estoy, 10 años después, escribiendo articulos y haciendo videos sobre Drupal, quien me lo iba a decir. Aunque he probado otros framworks y cms, me quedo con Drupal de lejos, pero Symfony y Django estan entre mis favoritos. Aficionado a la montaña, la bicicleta, y el comer, de eso que no falte.