Composition vs Inheritance vs Delegation with simple examples · Software Engineering
Composición (Composition)
La composición no es más que tener una clase con sus métodos y atributos, y relacionarla con otra clase distinta mediante la creación de un atributo dentro de la clase la cual necesite de su relación, y sus métodos y atributos.
La composición permite una mayor separación de responsabilidades, ya que cada objeto tiene su propia responsabilidad y puede ser reutilizado en otras tareas.
La composición establece una relación “tiene-un”.
Por ejemplo; Un coche tiene-un motor.
// Clase Motor
public class Motor {
private int potencia;
public Motor(int potencia) {
this.potencia = potencia;
}
public int getPotencia() {
return potencia;
}
}
// Clase Coche
public class Coche {
private Motor motor; // Atributo de clase Motor, el cual se utilizara para delegar tareas
private String marca;
public Coche(String marca, int potencia) {
this.marca = marca;
this.motor = new Motor(potencia);
}
// Vemos como en los métodos NO DELEGAN, es decir, no llaman a otro método
// creado en la otra clase, sino que tienen si propio código
public void encenderMotor() {
System.out.println("El motor del " + marca + " ha sido encendido.");
}
public void mostrarInformacion() {
System.out.println("Marca: " + marca + ", Potencia del motor: " + motor.getPotencia());
}
}
public class Main {
public static void main(String[] args) {
Coche coche = new Coche("CUPRA", 150);
coche.encenderMotor();
coche.mostrarInformacion();
}
}
Delegación (Delegation)
La delegación tiene la filosofía de delegar responsabilidades, es como tener a un jefe, que delega tareas a sus empleados (si le piden de hacerlas él las hace el mismo y no delega, pero en caso contrario las delega), y estos mismos también pueden subdelegarlos.
La diferencia entre la delegación y la composición, radica en que la “delegación” implica que una clase delega una tarea a otro objeto, con lo que simplemente llama a métodos del objeto para realizar tareas específicas.
La delegación establece una relación “haz-esto-por-mí”.
Por ejemplo; Haz-sumar-por-mí, Haz-restar-por-mí, Haz-multiplicar-por-mí, Haz-dividir-por-mí
// Clase que representa la operación matemática
class OperacionMatematica {
public int sumar(int a, int b) {
return a + b;
}
public int restar(int a, int b) {
return a - b;
}
public int multiplicar(int a, int b) {
return a * b;
}
public int dividir(int a, int b) {
if (b != 0) {
return a / b;
} else {
throw new ArithmeticException("No se puede dividir por cero");
}
}
}
// Clase que delega la responsabilidad de realizar operaciones matemáticas
class Calculadora {
private OperacionMatematica operaciones;
public Calculadora() {
this.operaciones = new OperacionMatematica();
}
// Aquí vemos la diferencia principal entre la Composition y la Delegation,
// la cual radica en que son métodos que únicamente hacen llamadas al método
// que desea que se realice la tarea.
public int sumar(int a, int b) {
return this.operaciones.sumar(a, b);
}
public int restar(int a, int b) {
return this.operaciones.restar(a, b);
}
public int multiplicar(int a, int b) {
return this.operaciones.multiplicar(a, b);
}
public int dividir(int a, int b) {
return this.operaciones.dividir(a, b);
}
}
public class Main {
public static void main(String[] args) {
Calculadora calculadora = new Calculadora();
int suma = calculadora.sumar(5, 3);
int resta = calculadora.restar(5, 3);
int multiplicacion = calculadora.multiplicar(5, 3);
int division = calculadora.dividir(5, 3);
System.out.println("Suma: " + suma);
System.out.println("Resta: " + resta);
System.out.println("Multiplicación: " + multiplicacion);
System.out.println("División: " + division);
}
}
Herencia (Inheritance)
La herencia nos permite que en una clase herede los atributos y métodos de otra clase. La herencia nos facilita la reutilización del código y la creación de una jerarquía de clases.
La delegación establece una relación “es-un”.
Por ejemplo; Un perro es-un animal.
public class Animal {
public void comer() {
System.out.println("Animal comiendo");
}
}
public class Perro extends Animal {
public void sonido() {
System.out.println("Guau");
}
}
public class Gato extends Animal {
public void sonido() {
System.out.println("Miau");
}
}
public class Main {
public static void main(String[] args) {
Perro miPerro = new Perro();
miPerro.comer();
miPerro.sonido();
}
}
TL;DR
La composición permite tener una clase en otra clase, en forma de atributo, y los métodos la pueden utilizar. Mientras que la Delegación también lo permite, pero con la diferencia en que existen métodos que simplemente delegan la tarea a otra, simplemente llamando el método que se quiera que haga la tarea.
Finalmente, para la herencia extiende o implementa la clase, con lo que la relaciona en forma de árbol.