Ley de Demeter

1
12042

La ley Demeter es una buena práctica para la programación orientada a objetos enfocada a reducir el acoplamiento entre clases.

Introducción

La ley Demeter es una buena práctica para la programación orientada a objetos enfocada a reducir el acoplamiento entre clases.

Probablemente te suene la siguiente manera de recuperar información de un objeto:


Universidad universidad;

[...]

System.out.println(universidad.getDepartamento(“Departamento de Informática”).getAsignatura(“Ingeniería del Software”).getProfesorCoordinador());

Como se puede ver, en este caso un objeto Universidad no tiene acceso de primer nivel al profesor coordinador de una asignatura. Esto implica que hay que hacer una llamada de tercer nivel a un objeto Asignatura para recuperar el profesor coordinador deseado. De esta manera, al objeto de tipo Universidad se le está dando información de la estructura del objeto de tipo Asignatura, al cual no tiene acceso directo, y además, se está confiando en cómo ese tercero proporciona la información.

¿Qué es lo que dice la Ley Demeter?

El fundamento de la Ley Demeter es el siguiente:

    Para todas las clases, C, y para todos los métodos, M, contenidos en C, todos los objetos a los cuáles M envía un mensaje deben de ser instancias de clases asociadas de la siguiente manera:

    • Las clases que definen a los argumentos de M, incluyendo a C
    • Las clases que definen a los atributos de C

    Se considera que los objetos creados por M, o por métodos a los que se llama desde M, y las variables globales son argumentos de M.

¿Cuál es el propósito de la Ley Demeter?

El principal objetivo de la Ley Demeter es reducir el acoplamiento entre clases, traduciéndose en una mejora en el mantenimiento del código. Lo hace disminuyendo el nivel de dependencia que tiene una clase con respecto a la estructura interna de otra clase que desconoce porque no es una “conocida” suya.

En el ejemplo anterior, si por alguna razón se modifica el comportamiento del método getProfesorCoordinador() o su interfaz, o incluso si se prescinde de la clase Asignatura, se hace necesario recodificar la pila de llamadas. En el ejemplo no sería costoso pero ¿que pasaría si sobre un proyecto real hay que hacer este tipo de recodificación repetidas veces, y no solo para un caso, sino para varios?

Al aplicar la Ley Demeter, pasaremos de recuperar el nombre del profesor coordinador de una asignatura de esta manera


Universidad universidad;

[...]

String profesorCoordinador = System.out.println(universidad.getDepartamento(“Departamento de Informática”).getAsignatura(“Ingeniería del Software”).getProfesorCoordinador());

a esta manera:

Universidad universidad;

[...]

System.out.println(universidad.getProfesorCoordinador(“Departamento de Informática”, “Ingeniería del Software”));

Las ventajas es que ante cualquier cambio, para obtener el profesor coordinador de una asignatura en este caso, disminuye el impacto en el mantenimiento y aumenta la adaptabilidad del código.

Veamos cómo hacerlo posible:

MainUniversidad.java

package com.autentia.tutoriales.demeterlaw;

public class MainUniversidad {

	public static void main(String[] args) {

	Asignatura asignatura;
	Departamento departamento;
	Universidad universidad;

	asignatura = new Asignatura();
	asignatura.setNombre("Ingeniería del Software");
	asignatura.setProfesorCoordinador("Autentio Pérez García");

	departamento = new Departamento();
	departamento.setNombre("Departamento de Informática");
	departamento.setAsignatura(asignatura.getNombre(), asignatura);	

	universidad = new Universidad("Universidad Autentia San Fernando");
	universidad.setDepartamento(departamento.getNombre(), departamento);

	System.out.println(universidad.getProfesorCoordinador("Departamento de Informática", "Ingeniería del Software"));

	}

}

Universidad.java

package com.autentia.tutoriales.demeterlaw;

import java.util.HashMap;
import java.util.Map;

public class Universidad {

	Map departamentos;
	String nombre;

	public Universidad(String nombre){
		this.departamentos = new HashMap();
		this.nombre = nombre;
	}


	public void setDepartamento(String nombreDepartamento, Departamento departamento){
		this.departamentos.put(nombreDepartamento, departamento);
	}

	public String getProfesorCoordinador(String nombreDepartamento, String nombreAsignatura){

		String profesorCoordinador = "";
		Departamento departamento = null;

		departamento = this.departamentos.get(nombreDepartamento);

		if(departamento != null){
		profesorCoordinador = departamento.getProfesorCoordinador(nombreAsignatura);
		}

		return profesorCoordinador;

	}

}

Departamento.java

package com.autentia.tutoriales.demeterlaw;

import java.util.HashMap;
import java.util.Map;

public class Departamento {

	Map asignaturas;
	String nombre;

	public Departamento(){
		asignaturas = new HashMap();
	}

	public String getNombre(){
		return this.nombre;
	}

	public String getProfesorCoordinador(String nombreAsignatura){

		String profesorCoordinador = "";
			profesorCoordinador = this.asignaturas.get(nombreAsignatura).getProfesorCoordinador();

		return profesorCoordinador;
	}

	public void setNombre(String nombre){
		this.nombre = nombre;
	}

	public void setAsignatura(String nombreAsignatura, Asignatura asignatura){
		this.asignaturas.put(nombreAsignatura, asignatura);
	}

}

Asignatura.java

package com.autentia.tutoriales.demeterlaw;

public class Asignatura {

	String nombre;
	String profesorCoordinador;

	public String getNombre(){
		return this.nombre;
	}

	public String getProfesorCoordinador(){
		return this.profesorCoordinador;
	}

	public void setNombre(String nombre){
		this.nombre = nombre;
	}

	public void setProfesorCoordinador(String profesorCoordinador){
		this.profesorCoordinador = profesorCoordinador;
	}

}

En la implementación se ve como si se realiza algún cambio en la clase Asignatura, la única clase que se vería afectada por ese cambio sería la clase Departamento. Los cambios a realizar si se se modifica el método getProfesorCoordinador() de la clase Asignatura estarían localizados en un único punto, que es el método getProfesorCoordinador(String asignatura).

Conclusiones

Aplicando la Ley Demeter hemos pasado de tener que modificar una pila de llamadas, realizada probablemente en varios lugares de la implementación, a tener que realizar la modificación en un único lugar, reduciendo el impacto de mantenimiento del código.
La Ley Demeter tiene desventajas, como es el tiempo que hay que dedicar a realizar métodos de envoltura y la disminución del rendimiento.

De todas maneras, como se dice en el Clean Code: “talk to friends, not to strangers”.

1 COMENTARIO

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad