S.O.L.I.D.

5 principios básicos de la programación orientada a objetos y el diseño

¿Qué ocurre cuando tenemos que modificar algo?

Lo más probable es...

que éste sea nuestro código y ...

que estemos tocando una pieza de abajo

¿Y ahora qué hacemos?

¿Quién nos ayuda?

Nos toca remangarnos y empezar a jugar

Entonces, ¿qué es SOLID?

  • Siempre
  • Olvido
  • Lo
  • Interesante del
  • Desarrollo

No, mentira

S.O.L.I.D. es el acrónimo de:

  • Single Responsability
  • Open Closed
  • Liskov Substitution
  • Interface Segregation
  • Dependency Inversion

DEMO


public void register(String email, String password){
  if (!email.contains("@"))
    throw new ValidationException("Email is not an email!");
  User user = new User(email, password);
  _database.save(user);
  MailMessage msg = new MailMessage("mysite@nowhere.com", email);
  _smtpClient.send(msg);
 }
        
ejemplo Single Responsability

Open/Closed Principle

Entidades software (clases, módulos, funciones, etc) deberían estar abiertas para extensión pero cerradas para modificación
  • Si 1 cambio impacta a varias entidades la aplicación no está bien diseñada
  • Debemos diseñar módulos que nunca cambien

¿Pero cómo hacemos esto?

ABSTRACCIÓN

DEMO


public void calcularBonos(){
  for(Empleado empleado : empleados){
    int bono = 0;
    switch(empleado.getTipo()){
      case PROGRAMADOR:
        bono = empleado.getSueldo()*2;
        break;
      case GERENTE:
        bono = empleado.getSueldo()*10;
        break;
    }
    empleado.setBono(bono);
  }
}
        
ejemplo Open/Closed Principle

Liskov Subtitution Principle

Métodos que usen referencias a clases base deben poder usar objetos de clases derivadas sin saberlo
  • Si tenemos una clase BASE y dos subclases SUB1 y SUB2 el código cliente tiene que referirse a BASE
  • No debemos pensar SUB1 es un BASE
  • Tenemos que pensar en SUB1 es reeplazable por una BASE

DEMO


public interface Duck { void swim(); }

public class DuckImpl implements Duck {
   public void swim() { /*do something to swim*/ }
}

public class ElectricDuck implements Duck {
   public void swim() {
      if (!isTurnedOn)
        return;
      //swim logic
   }
}

public void makeDuckSwim(Duck duck){
    duck.swim();
}
        
ejemplo Liskov Sustitution Principle

Interface Segregation Principle

Los clientes no deberían estar forzados a depender de interfaces que no utilizan
  • Las interfaces gordas o contaminadas deben dividirse en varios grupos de funciones
  • Cada grupo será implementado por distintos tipos de clientes

DEMO


public interface Animal {
  void alimentar();
  void acariciar();
}

public class Perro implements Animal {
   public void alimentar() { /*alimentando al perro*/ }
   public void acariciar() { /*acariciando al perro*/}
}
        
ejemplo Interface Segregation Principle

public class Escorpion implements Animal {
 public void alimentar() { /*alimentando al escorpión*/ }
 public void acariciar() {
   /*Estás nominado a un premio Darwin y posiblemente lo ganes*/
 }
}
      
ejemplo Interface Segregation Principle

Dependency Inversion Principle

Módulos de alto nivel no deben depender de módulos de bajo nivel. Ambos deben depender de abstracciones.
Abstracciones no deben depender de detalles. Los detalles deben depender de las abstracciones

¿Cómo lo hacemos?

  • Inyección de dependencias
  • IoC (Inversión de control)

DEMO


public class Volvo {
  private B20 engine;
  public Volvo (){engine = new B20()}
}
        
ejemplo Dependency Inversion Principle

¿Preguntas?

¿?