Favorecer relaciones TIENE UN sobre relaciones ES UN en clases

Ayer no acerté a explicar por qué es preferible la composición sobre la herencia así que me di una vuelta por el ejemplo de los patos de Head First Design Patterns que es con el que se presenta el patrón Estrategia.

El ejemplo comienza teniendo una clase base Duck de la que heredan algunos patos, entre ellos RubberDuck. Cuando definen el método fly() en la clase Duck, se dan cuenta de que absolutamente todos los patos tendrán ese método incluso el pato de goma al que le tendrían que implementar el método sin código.

Para evitar tener código sin sentido se cambia el método fly() en Duck por una interfaz Flyable con el método fly(). Esta interfaz la implementan sólo los patos que pueden volar, así que RubberDuck no implementaría fly() de Flyable. El problema aquí es obvio: No es nada reusable, ya que habría que escribir el código para volar en todas las implementaciones que se defina.

Esas dos opciones anteriores eran relaciones ES UN entre las clases y su comportamiento.
1. RubberDuck ES UN Duck -que tiene el método fly() y no debería-.
2. MallardDuck ES UN Flyable -que tiene el método fly()-.

En este primer ejemplo, solucionan su problema de patos a través de la composición. En la clase base Duck incluyen un FlyBehavior que es al que delegan el mecanismo de vuelo del pato (o de no vuelo).

FlyBehavior es una interfaz y sus implementaciones son FlyWithWings y FlyNoWay. Cada clase que hereda de Duck elige si quiere tener un FlyBehavior de tipo FlyWithWings o como el RubberDuck que en el constructor elige un FlyBehavior de tipo FlyNoWay.

Este mecanismo de composición es una relación TIENE UN y es mucho más flexible que la relación ES UN que “define demasiado” el tipo y obligaría a una engorrosa y muy larga jerarquía para implementar todos los comportamientos posibles.

Duck TIENE UN FlyBehavior al que delegará más adelante el mecanismo para volar.
RubberDuck TIENE UN FlyBehavior y ha elegido que sea de tipo FlyNoWay.

diagramaClases

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s