Introducción
En este artículo hablaremos sobre las cláusulas de guarda, una técnica que nos permite mejorar la mantenibilidad
y legibilidad de nuestro código.
¿Qué son las cláusulas de guarda?
Las cláusulas de guarda son una técnica que nos permite simplificar la lógica de nuestras funciones reorganizando
el código para que los casos excepcionales se manejen primero y podamos olvidarnos de ellos. Esto nos permite reducir
la complejidad cognitiva y nos ayuda a mejorar la legibilidad de nuestro código, eliminando niveles innecesarios
de indentación.
¿Cómo implementar las cláusulas de guarda?
En primer lugar, debemos identificar los bloques de código que son fácilmente refactorizables, los ejemplos clásicos
suelen ser bloques de código con varios if-else anidados en los que en cada bloque se devuelva un valor diferente o se
lance una excepción.
Un ejemplo clásico sería el de un bloque de código que se encarga de comprobar si un usuario de un cliente tiene permisos
suficientes para ejecutar una acción.
Antes de la refactorización:
public function check(...) {
if ($user) {
if ($user->client()->hasFeature('XXX')) {
if ($user->hasPermission('YYY')) {
// do something
} else {
throw new ActionDenied();
}
} else {
throw new FeatureNotEnabled();
}
} else {
throw new UserNotFound();
}
}
Como se puede ver el código queda muy anidado y poco legible, haciendo que tu carga cognitiva sea mayor ya que hay
que ir teniendo en cuenta condiciones anteriores para entender el flujo del código.
Después de la refactorización:
public function check(...) {
if (!$user) {
throw new UserNotFound();
}
if (!$user->client()->hasFeature('XXX')) {
throw new FeatureNotEnabled();
}
if (!$user->hasPermission('YYY')) {
throw new ActionDenied();
}
// do something
}
Cuando lo que se lanzan son excepciones, todavía podemos ir un poco más lejos extrayendo cada bloque if a un método
para que quede más semántico:
public function check(....) {
$this->ensureUserExists();
$this->ensureClientHasFeatureEnabled();
$this->ensureUserHasPermission();
// do something
}
private function ensureUserExists() {
if (!$user) {
throw new UserNotFound();
}
}
private function ensureClientHasFeatureEnabled() {
if (!$user->client()->hasFeature('XXX')) {
throw new FeatureNotEnabled();
}
}
private function ensureUserHasPermission() {
if (!$user->hasPermission('YYY')) {
throw new ActionDenied();
}
}
Ahora, una vez aplicadas las cláusulas de guarda, el código queda mucho más limpio y legible, haciendo que los casos
excepcionales se manejen al principio y olvidarnos de ellos en los siguientes pasos.
Conclusiones
El uso de cláusulas de guarda puede transformar la manera en que estructuramos nuestro código, permitiéndonos
simplificar la lógica y mejorar la legibilidad de nuestras funciones. Al manejar las excepciones y casos especiales
al principio, el código se vuelve más limpio y semántico, además de más robusto y eficiente.
Te recomiendo que pruebes a aplicar esta técnica en tu código, unida a la extracción de fragmentos de código a métodos
cuando las condiciones sean demasiado complejas, y veréis cómo mejora la calidad de vuestro código.
También puedes pasarte por mi canal de YouTube para ver el vídeo sobre cláusulas de guarda:
{{< youtube 3QjVGAKxXKA >}}
¡Gracias por leer y espero que te haya gustado el artículo!
PD: Si tenéis cualquier duda podéis poneros en contacto conmigo enviando un DM a twitter.
0 comentarios