lunes, 19 de agosto de 2013

Programación orientada a Interfaces

Uno de los temas más importante y quizás que muchos desarrolladores no toman en cuenta, es la programación basada en interfaces o programación orientada a interfaces, y este tema es uno de los más importantes para tener buenas prácticas de programación y tener códigos escalables.

 Y bueno.



¿Qué es la Programación orientada a Interfaces?

Bueno, la programación orientada a interface esta basada en la creación de una interface a la cual se le generan n implementaciones para así disminuir el código intrusivo en nuestro sistema, creando atributos de tipo interface en lugar de clases concretas. 
veamoslo con ejemplo:

Supongamos que tenemos la interface Herramienta.


public interface Herramienta {

String getNombre();
String getHabilidad();


}


Esta interface contiene dos métodos, bueno sabemos que en una interface todos sus métodos no tienen implementación y por dafult son públicos.  solo se definen los métodos pero no se implementan a diferencia de las clases concretas.


¡¡¿¿¿???!!! What do that fuck?? que es una interface y que es una clase concreta.

ok.

bueno les presento a la interface. :)

public interface Interface{

void nombreMetodo();
String nombreMetodo();


}


Ahora les presento a la clase concreta :)


public class ClaseConcreta{

String nombreMetodo(){

         }
String getHanombreMetodobilidad(){
     
        }


}


ok, bien, entonces en resumen, una interface no tiene implementación de sus métodos, mientras que una clase concreta tiene implementación en todos sus métodos, esto nos lleva a recordar otro tipo de clase llamada clase Abstracta, que se encuentra entre las interfaces y las clases concretas. ya que puede ser un híbrido, algunos de sus métodos pueden ser abstractos y otros no. veamoslo como sería una clase abstracta.



public abstract class ClaseAbstracta {

/**
* @param args
*/
public void metodoConcreto(){
}
abstract void metodoAbstracto();

}

como podemos ver, para definir una clase abstracta, debemos anteponer la palabra reservada abstract antes de la palabra reservada class, y si queremos que un método sea abstracto debemos anteponer la palabra abstract antes del tipo de retorno del método.


entonces visto esto, vemos que tenemos 3 niveles de abstracción.

1.- primero las interfaces --> 100% abstractas

2.- segundo las clases abstractas --> no se sabe, depende como lo decida el programador.

3.- tercero las clases concretas  --> 100 % concretas .


ya aclarado esto, vamos a continuar.

ok, regresemos a la interface Herramienta.

public interface Herramienta {

String getNombre();
String getHabilidad();


}

upss, apenas voy a empezar con el tema :S  ,  ok, pues como ya tenemos la interface, ahora vamos a crear una implementación de la misma, es decir una clase que implemente sus dos métodos en este caso.


public class Martillo implements Herramienta {

@Override
public String getNombre() {
// TODO Auto-generated method stub
return "martillo";
}

@Override
public String getHabilidad() {
// TODO Auto-generated method stub
return "golpear clavos";
}
}

una clase para poder implementar una interface debe hacerlo con el operador implements seguido del nombre de la interface a implementar, de hecho puedes implementar más de una interface en una misma clase, a diferencia de la herencia que solo puedes heredad de una.


podemos ver que si no ponemos los métodos de getNombre y getHabilidad nos marcaría error en tiempo de compilación diciendo o que la clase no es abstracta o que no hemos implementado los métodos de la interface, en este caso es la segunda opción.


bien, yo creo que todos vamos bien hasta aquí, así que seguiré para crear otra implementación llamada Jeringa:



public class Jeringa implements Herramienta {

@Override
public String getNombre() {
// TODO Auto-generated method stub
return "jeringa";
}

@Override
public String getHabilidad() {
// TODO Auto-generated method stub
return "hacer sufrir";
}
}


cae bajo las mismas reglas que martillo.


ahora que ya tenemos dos clases concretas ( Martillo y Jeringa) que implementan de la interface Herramienta, vamos a crear otra clase concreta llamada Trabajador.


la cual quedaría de la siguiente forma.

public class Trabajador {

private Herramienta herramienta;



public Herramienta getHerramienta(){

       return herramienta;
}

public void setHerramienta(Herramienta herramienta){

   this.herramienta=herramienta;

 }

}

podemos ver que tiene un atributo de tipo Herramienta, el cual es un tipo interface.


Ya que estamos hablando de manera muy abstracta, al trabajador no le importa el tipo de Herramienta que utilice, pero si le damos vida a ese trabajador, por así decirlo, es decir que ese trabajador fuera un chofer, un che, un ingeniero, un vendedor, etc, etc, etc. su herramienta podría variar, en términos de programación estamos dejando de ser tan intrusivos en la clase Trabajador, ya que el puede implementar su Herramienta sin alterar el código de Trabajador, bueno veámoslo como podemos cambiar dicha implementación de su herramienta.
para eso vamos a crear una clase con un método Main.

Como podemos ver en la imagen, en la linea 21, tenemos el proceso de downcasting, que no es más que implementar una interface con alguna de sus implementaciones.

Se llama downcasting, porque si lo vemos de una forma jerárquica, sería de la siguiente manera.



 entonces como martillo o Jeringa esta abajo de Herramienta, por eso se llama downcasting , anyway ....


bien, ahora vamos a implementar la misma  herramienta pero como Jeringa, así que veamos la imagen.




Como podemos ver con tal solo cambiar una palabra, nuestra implementacion del método getNombre() de la herramienta cambio, pero bueno estamos hablando de una insignificante salida en un método print(), sin embargo si lo trasladamos a un sistema real, esto nos ahorraría mucho tiempo de programación y nuestro sistema sería altamente escalable y no intrusivo, que quiero decir con no intrusivo, bueno a la clase Trabajador no se le tubo que hacer ningún cambio al tener un tipo interface en lugar de clase concreta como atributo.

Herramienta herramienta;


pero como se vería si fuera código intrusivo?..,
a pues así.

Martillo martillo;
o
Jeringa jeringa;


y pues esto nos hubiera llevado a cambiar también los constructores y setters y getters de nuestro atributo, que feo :(

pero al usar la programación orientada a interfaces nos ahorramos eso.

bueno espero les sirva y saludos.






7 comentarios:

  1. excelente explicacion de las bondades de la programación orientada a interface.saludos

    ResponderBorrar
  2. Si Herramienta hubiera sido una clase abstracta, el codigo tambien hubiera quedado no intrusivo, ya que Trabajador tiene una relacion con Herramienta, porque no conviene hacer Herramienta como abstracta pero si como interface??saludos.

    ResponderBorrar