El todo es mayor que la suma de sus partes
-Aristóteles
Esta cita se atribuye a Aristóteles. El punto básico es la sinergia. En el exitoso libro de Stephen Covey Los 7 hábitos de la gente altamente efectiva, su sexto hábito es la sinergia. Lo que es cierto en las organizaciones también lo es en la informática. El cuerpo de un objeto es más valioso que su individuo. En informática, utilizamos el término composición.
Composición
Entonces, ¿qué entendemos por composición? «La composición es uno de los conceptos fundamentales en la programación orientada a objetos. Describe una clase que hace referencia a uno o más objetos de otras clases en variables de instancia. Esto permite modelar una asociación has-a entre objetos». Así es como lo describe Stackify aquí. Piensa en ello como una orquesta. Un intérprete está bien pero cuando tienes a todo el grupo junto la música es más rica y profunda.
Beneficios
El principal beneficio para el código creado con una composición adecuada es la reutilización. Si lo diseñas correctamente debería ser fácil de reutilizar. Si no, entonces puede ser bastante engorroso. Junto con eso es una API o Interfaz de Programación de Aplicaciones intuitiva y limpia. Como programador experimentado de Java, he oído a mucha gente lamentar el diseño de la API de hilos de Java. Un buen diseño debería permitirte cambiar algo internamente y no cambiar la forma en que otros interactúan con él.
Ejemplos
Creemos un ejemplo para que podamos ver cómo es la composición en Java.
Aquí tenemos nuestra clase Role definida.
La clase Role se utiliza en esta clase Employee. En la composición, se diría que la clase Employee «tiene un» Role.
Ocultando
En nuestro ejemplo de API, las clases HotDogGrinder y HotDogGrill son paquete-privado y no se puede acceder a ellas desde el exterior.
Aquí tenemos la cara pública de nuestra API, HotDogMachine. Esta clase tiene una referencia a las dos clases internas que estamos ocultando con nuestro diseño de la API.
Composición vs Herencia
La composición y la herencia pueden ser confundidas por los desarrolladores. Como señala Steven Lowe en esta entrada del blog de ThoughtWorks, tenemos que elegir cuidadosamente cuál utilizar.
Comparte la regla general que se oye a menudo, «favorecer la composición sobre la herencia». Como con cualquier regla empírica tenemos que entender que no siempre se aplican. Así que vamos a aclarar algunas cosas antes de seguir adelante.
Definamos la herencia, ya que hemos hablado ampliamente de la composición. La herencia es uno de los fundamentos de la programación orientada a objetos. Por ejemplo, si tenemos una clase comida entonces la clase pan heredaría de la clase comida. Mientras que la composición se ocupa de los elementos que forman parte de una unidad mayor.
Lowe nos recuerda que cuando se podría utilizar cualquiera de las dos cosas tenemos que hacer dos preguntas diferentes. Primero, «La representación/implementación de sus conceptos de dominio es una dimensión». Esencialmente si ambos están en el mismo dominio la herencia es probablemente su mejor apuesta. En segundo lugar, «La semántica de tus conceptos de dominio y su relación entre ellos es una segunda dimensión». Los componentes que creas empiezan a reenviar a otro esto podría ser una señal de que podrías necesitar reconsiderar el uso de la herencia en su lugar.
La composición es un gran principio en el desarrollo de software que muchos de nosotros los profesionales estropeamos. Yo mismo lo he hecho al crear soluciones sin enfocarlo correctamente. Una rápida discusión en una pizarra con un colega o dibujando algo en un papel puede ayudarte a entender cuando hay una relación «has-a» entre dos objetos. Después de leer esto también deberías entender los beneficios y saber cómo utilizarlo en un ejemplo. Intenta construir algún ejemplo y úsalo, entonces deberías saber si estás en el camino correcto o quizás la herencia podría ser un mejor camino.