Objetos y Estructuras de Datos, Código Limpio

Abstracción de Datos

Intenta no mostrar al usuario los detalles de los datos. Intenta mostrarle términos abstractos.

Ejemplo:

En una clase Vehículo, en vez de:

  • Implementar un método que nos devuelva la capacidad en Litros de Gasolina que nos queda en el deposito.
public interface Vehiculo {
    float getLitrosDeGasolinaEnElDeposito();
}
  • Mejor Implementarlo abstracto y que devuelva el porcentaje del deposito.
public interface Vehiculo {
    float getPorcentajeCombustibleEnElDeposito();
}

¿Por qué?

  • ¿Y si el vehículo en vez de gasolina es de gasoil, keroseno, GLP….?
  • ¿Y si en vez de Litros se midiera en Galones?

Antisimetria de Datos y Objectos

Objetos

Ocultan sus datos tras abstracciones y muestran funciones que operan en dichos datos.

Estructura de Datos

Muestra sus datos y carece de funciones con significado.

 

Ejemplo Solución Orientada a Objectos

  • Facilita la inclusión de nuevas clases sin cambiar las funciones existentes.
  • Dificulta la inclusión de nuevos métodos ya que es necesarios cambiar todas las clases.

 

Interface Forma

public interface Forma {
    public double area();
}

 

Clase Rectangulo

public class Rectangulo implements Forma {
    private double altura;
    private double anchura;


    public Rectangulo(double altura, double anchura){
        this.altura = altura;
        this.anchura = anchura;
    }

    @Override
    public double area() {
        return altura * anchura;
    }
}

 

Clase Cuadrado

public class Cuadrado implements Forma {
    private double lado;


    public Cuadrado(double lado){
        this.lado = lado;
    }

    @Override
    public double area() {
        return lado * lado;
    }
}

 

  • El método area() es polimórfico.
  • Si implemento una nueva Forma, ninguna de las funciones existentes se ven afectadas.
  • Si añado una nueva función a Forma, habrá que cambiar todas clases que implementen de ella.

Ejemplo Solución Estructura de Datos

  • Facilita la inclusión de nuevos métodos sin afectar a las clases existentes.
  • Dificulta la inclusión de nuevas clases ya que habría que cambiar todos los métodos.

 

Clase Geometría

public class Geometria {
    public double area(Object forma) throws Exception {

        if (forma instanceof Cuadrado){
            Cuadrado cuadradoEjemplo = (Cuadrado) forma;
            return cuadradoEjemplo.lado * cuadradoEjemplo.lado;
        }

        else if (forma instanceof Rectangulo){
            Cuadrado cuadradoEjemplo = (Cuadrado) forma;
            return cuadradoEjemplo.lado * cuadradoEjemplo.lado;
        }


        throw new Exception();
    }

}

 

Clase Cuadrado

public class Cuadrado {
    public double lado;
}

 

Clase Rectángulo

public class Rectangulo {
    public double alto;
    public double ancho;
}

 

  • Si implemento una nueva clase, habría que cambiar todas las funciones implementadas en Geometría.
  • Si añado una nueva función a Geometría, ninguna de las clases se verían afectadas.

Entonces, ¿que usamos?

  • Si queremos añadir nuevos tipos de datos en lugar de funciones –>  Programación Orientada a Objetos
  • Si queremos añadir nuevas funciones en lugar de tipos de datos –> Procedimientos y Estructura de Datos

La idea que todo es un objeto es un mito. A veces queremos estructuras sencillas de datos con procedimientos que operen en las mismas.

Ley de Demeter

Un módulo no debe conocer los entresijos de los objectos que manipula.

Los objectos ocultan sus datos y muestran operaciones, lo que no muestra su estructura interna.

Un Método (metodoEjemplo) de una Clase (claseEjemplo) solo debe invocar los métodos de:

  • claseEjemplo.
  • Un objecto creado por metodoEjemplo.
  • Un objecto pasado como argumento a metodoEjemplo.
  • Un objecto en una variable de instancia de claseEjemplo.

El método no debe hablar con desconocidos, solo con amigos.

 

String directorioSalida = objectoEjemplo.getOpciones().getDirectorioBruto().getDirectorioAbsoluto();

El modulo contenedor sabe que:

  • El objectoEjemplo tiene opciones
  • Que opciones tiene un una función DirectorioBruto
  • Que directorioBruto tiene una funcion ruta absoluta.

La función sabe demasiado, sabe como desplazarse por numerosos objectos diferentes.

Si son objetos –> Si incumple la ley de Demeter porque debería ocultar su estructura interna.

Si son Estructuras de Datos–> No aplica la Ley de Demeter ya que muestran su estructura interna con naturalidad.

String directorioSalida = objectoEjemplo.getOpciones.getDirectorioBruto.getDirectorioAbsoluto;