Composición en Clases con C#

En esta ocasión hablaremos sobre el tema de relaciones entre clases, más específicamente la relación de composición. Este concepto hace referencia dentro del contexto de la Programación Orientada a Objetos, a aquella clase que a su vez está conformada por otra u otras clases.

La composición se usa principalmente para indicar que un conjunto de clases comparten el ciclo de vida la clase a la que forman, la que forma el todo, es decir, si la clase del todo se destruye, también se destruirán las clases que la componen.

Veamos un ejemplo utilizando la clase Auto, el siguiente diagrama de clases de UML (Unified Modeling Language) muestra como dicha clase esta compuesta por las clases Motor, Odometro y TanqueCombustible.

Composicion1
Diagrama de clases en UML mostrando la composición de la clase Auto

En el diagrama se muestra la clase Auto compuesta por el resto de las clases, en el lenguaje UML la relación de composición se denota por una flecha con punta de diamante en el extremo que apunta hacia la clase que representa el todo, en este caso la clase Auto.

Visto de manera práctica, este diagrama se puede traducir en código fuente para cada una de las clases involucradas, veamos primeramente el código para la clase Auto.

class Auto
    {
        //Zona de Atributos
        Motor miMotor = new Motor(20);
        Odometro miOdometro = new Odometro();
        TanqueCombustible miTanque = new TanqueCombustible();
        //Zona de Métodos       
        public void ArrancarAuto()
        {
            miMotor.EncenderMotor();
        }
        
        public void AvanzarAuto(int velocidad)
        {
            
            miTanque.setCantidadCombustibleTanque(40);
            int gastoCombustible;
            int milliseconds = 10;

            if (velocidad < 20)
                gastoCombustible = 1;
            else
                if ((velocidad % 10) == 0)
                    gastoCombustible = 2;
                else
                    gastoCombustible = 1;

            for (int i=0; ; i++)
            {
                miOdometro.setDistanciaRecorrida(i);
                
                if ((miOdometro.getDistanciaRecorrida() % 100) == 0)
                    miTanque.setCantidadCombustibleTanque(
                        miTanque.getCantidadCombustibleTanque() - gastoCombustible);

                if (miTanque.getCantidadCombustibleTanque() == 0)
                {
                    Console.WriteLine(i + " - [" +
                    miTanque.getCantidadCombustibleTanque() + "]");
                    miMotor.ApagarMotor();
                    break;
                }
                Console.WriteLine(i + " - ["+
                    miTanque.getCantidadCombustibleTanque() + "]");

                Thread.Sleep(milliseconds);

                Console.Clear();
            }                
        }
    }

A continuación veamos el código para la clase Motor

class Motor
    {
        //Zona de Atributos
        private Boolean enciendeMotor;
        
        //Zona de Métodos
        public Motor(int cantidadCombustible)
        {
            //validar si existe combustible
            if (cantidadCombustible > 0)
                this.enciendeMotor = true;
            else
                this.enciendeMotor = false;
            
        }
        
        public bool EncenderMotor()
        {
            if (enciendeMotor)
            {
                Console.WriteLine("Encendiendo el auto");
                return true;
            }
            else
            {
                Console.WriteLine("No hay combustible");
                return false;
            }
        }

        public bool ApagarMotor()
        {
            Console.WriteLine("Apagando el motor");
            return false;
        }
    }

Ahora toca el turno de la clase Odometro

 class Odometro
    {
        //Zona de Atributos
        private int distanciaRecorrida;

        //Zona de Métodos
        public void setDistanciaRecorrida(int distanciaRecorrida)
        {
            this.distanciaRecorrida = distanciaRecorrida;
        }

        public int getDistanciaRecorrida()
        {
            return distanciaRecorrida;
        }
    }

Finalmente tenemos el código para la clase TanqueCombustible

 class TanqueCombustible
    {
        //Zona de Atributos
        private int capacidadTanque;
        private int cantidadCombustibleTanque;
        //Zona de Métodos
        public TanqueCombustible()
        {
            this.capacidadTanque = 100;
        }

        public void setCantidadCombustibleTanque(int cantidadCombustible)
        {
            if(cantidadCombustible > capacidadTanque || cantidadCombustible < 0)
                Console.WriteLine("Error al agregar combustible al tanque.");
            else
                this.cantidadCombustibleTanque = cantidadCombustible;
        }

        public int getCantidadCombustibleTanque()
        {
            return cantidadCombustibleTanque;
        }
    }

Muy bien, ya que tenemos todas las clases ahora solo recalquemos el detalle de la composición en la clase Auto donde, en las lineas 4, 5 y 6 podemos observar la declaración de objetos de las diferentes clases que componen a Auto. Esto es suficiente para poder realizar la composición en términos prácticos.

La ejecución de la solución requiere una instancia de la clase Auto, la cual generamos dentro del main en la clase Program del proyecto de Visual Studio. El programa en si muestra como en función de una determinada cantidad de gasolina dentro del tanque, se puede hacer funcionar el motor y en consecuencia recorrer una cierta distancia.

class Program
{
static void Main(string[] args)
{
Auto Sonic = new Auto();
Sonic.AvanzarAuto(40);
Console.ReadKey();
}
}

La salida del programa en la consola mostrará de manera simulada el avance de una cierta distancia por parte del vehículo a la vez que se va consumiendo la cantidad de combustible existente dentro del tanque. Al llegar el combustible a cero el Auto se apaga.

salida

Espero que les sirva este ejemplo.

2 comentarios en “Composición en Clases con C#

  1. Hola, es una crítica construcitva, para que no lo tomes a mal, cuando des un ejemplo de lógica de programación en POO, relacionado algún tema que tenga que ver con orientación a objetos. Te pido que seas lo más claro posible. Porque en el código que vos publicaste, te falta colocar algunas bibliotecas, algunos using. Ejemplo de la claseThread.

    Me gusta

Deja un comentario