Sie sind auf Seite 1von 11

Programacin Orientada a Objetos: Asociacin vs Composicin

En lo personal, conceptos que me parecieron bastante difciles de comprender cada vez que trataba de estudiar Programacin Orientada a Objetos. Por eso tratar de crear una explicacin sencilla para los que ahora se ven en mi situacin. Porque el que domines un lenguaje de programacin no te garantiza que hars un buen diseo del sistema. Los dos conceptos que debes conocer cmo mnimo cuando intentas descifrar la forma en que tus objetos deben interactuar son Asociacin y Composicin.

Asociacin
La asociacin se podra definir como el momento en que dos objetos se unen para trabajar juntos y as, alcanzar una meta. Un punto a tomar muy en cuenta es que ambos objetos son independientes entre s, veremos un poco ms adelante qu implicacin tiene esto. Para validar la asociacin, la frase Usa un, debe tener sentido:

El ingeniero usa una computadora El cliente usa tarjeta de crdito.

Composicin
En caso contrario, la composicin es un tipo de relacin dependiente en dnde un objeto ms complejo es conformado por objetos ms pequeos. En esta situacin, la frase Tiene un, debe tener sentido:

El auto tiene llantas La porttil tiene un teclado.

Y como sta mini gua no va a mencionar nada de UML. Vamos a ver directamente en cdigo cmo se veran representadas ambos tipos de relaciones. El cdigo es Java, pero funciona para cualquier lenguaje de programacin orientado a objetos.

Cmo implementar Asociacin


Representaremos la relacin: El cliente usa tarjeta de crdito.
Cdigo :

public class Customer {

private int id; private String firstName; private String lastName; private CreditCard creditCard;

public Customer() { //Lo que sea que el construtor haga }

public void setCreditCard(CreditCard creditCard) { this.creditCard = creditCard; }

// Ms cdigo aqu }

La explicacin viene ms adelante para darles oportunidad que hagan sus propias comparaciones.

Cmo implementar Composicin


Representaremos la relacin: La porttil tiene un teclado.
Cdigo :

public class Laptop { private String manufacturer; private String model; private String serviceTag; private KeyBoard keyBoard = new KeyBoard();

public Laptop() { //Lo que sea que el constructor haga }

Muy similar, pero hay una gran diferencia: Podemos crear un objeto de tipo Customer y asignarle un CreditCard ms tarde mediante el mtodo setCreditCard. Pero si creamos un objeto Laptop, de entrada sabremos que tendr un teclado ya creado, puesto que la variable de referencia keyBoad es declarada e inicializada al mismo tiempo. Llamaremos a las clases Customer y Laptop, clases contenedoras. De ambos casos podemos deducir que:

En la asociacin:
1. Customer es independiente de CreditCard, puesto que el cliente puede existir sin necesidad de tener asignada una tarjeta de crdito. Dmosle tiempo para que la tramite, Pero no lo dejemos ir! 2. Se puede asignar o retirar la tarjeta de crdito, sin que la existencia del Cliente se vea afectada (No debera verse afectada, esto significa que Customer no debe tronar si no hay un CreditCard presente).

En la composicin:
1. Los objetos que componen a la clase contenedora, deben existir desde el principio. (Tambin pueden ser creados en el constructor, no slo al momento de declarar las variables como se muestra en el ejemplo). 2. No hay momento (No debera) en que la clase contenedora pueda existir sin alguno de sus objetos componentes. Por lo que la existencia de estos objetos no debe ser abiertamente manipulada desde el exterior de la clase.

Tiempo de vida de un objeto


Para que quede ms clara la diferencia entre Asociacin y Composicin, entendamos adems, lo que es el tiempo de vida de un objeto. Se define como el tiempo que transcurre desde que un objeto es creado hasta que se destruye. Aplicando esto a la asociacin, tenemos que los tiempos de vida de ambos objetos se cruzan mientras estn trabajando juntos, esto es, mientras se encuentran asociados, pero no significa que se hayan creado al mismo tiempo. En el ejemplo del cliente, puede ser que primero se cree el cliente, despus la tarjeta de crdito y luego viene la asociacin. O incluso se puede crear antes la tarjeta de crdito. Sus tiempos de vida se cruzan slo mientras la tarjeta de crdito est asociada al cliente. En la composicin, tanto los objetos componentes como la clase contenedora, nacen y mueren al mismo tiempo. Esto es, tienen el mismo tiempo de vida. Al ser una relacin demasiado dependiente, si cualquier objeto muere, se lleva consigo a todos los dems. En el ejemplo de la porttil, si mi teclado se descompone, mi laptop ya no es funcional. Y no vengan con que puedo reemplazar el teclado, y que puedo seguir trabajando con la misma porttil y un teclado distinto. Tienes que analizarlo de la siguiente forma:

Si a tu auto, se le poncha una llanta, podrs reemplazarlas siempre y cuando lo tengas estacionado (Es como modificar el cdigo de la clase, el sistema no est en funcionamiento). Pero Qu pasa si

tu auto estuviera en marcha?, puedes cambiarla al vuelo e impedir que el auto se detenga? No se puede, por lo tanto tu auto deja de cumplir su objetivo en ese momento y para fines prcticos, ya no sirve. Entonces es lo mismo con los objetos ya creados, no puedes reemplazarles componentes al vuelo porque no existe (no debera) mecanismo alguno en la definicin de la clase, que te lo permita.

Asociacin o Composicin? depende


Habr casos en que ser difcil determinar qu tipo de relacin usar cuando ambas encajan:

Un reloj tiene manecillas Un reloj usa manecillas (Para dar la hora, claro).

As que debes tomar en cuenta qu tanta flexibilidad te dara implementar una u otra. Desde el punto de vista de fabricante de relojes, necesito tener control sobre cada una de las piezas que conforman mis relojes; as, si alguna pieza sale defectuosa, puedo reemplazarla antes que mi producto llegue al mercado. Me conviene la asociacin. Pero desde el punto de vista de Consumidor final, Si mis manecillas se friegan, pues tiro el reloj entero y me compro uno nuevo. Lo vera como composicin. Y terminar diciendo lo mismo que dicen la mayora de las lecturas que tratan este tema: Todo depende del cristal con que se mire (Ms propiamente dicho, el que necesites). Pero espero y haya logrado darles una perspectiva ms clara de cmo y cundo aplicar Asociacin y Composicin.

Diferencias entre Agregacin y Asociacin


1- La Agregacin son siempre colecciones, o arrays! O algo que sirva de contenedor para agregar ms de un objeto, aunque agreguemos uno solo.(si no seria settear y no agregar) 2- La Agregacin cuenta con dos mtodos: uno para agregar un solo objeto a la lista, y el otro para quitarlo de la misma. 3- La agregacin puede, como no, tener los mtodos setter y getter , mientras que la asociacin siempre los tiene , que ponen y obtienen una variable referencia del mismo tipo de la variable de instancia o de clase, en este caso list.

Agregacion y Composicion
He visto demasiadas discusiones vicentinas sobre las diferencias entre la agregacin y la composicin en los diagramas de clases de UML. Es ms, cada cierto tiempo, alguien surge y me pregunta cual es la diferencia en el cdigo y me explica sus propias teoras sobre esta cuestin, este debate es casi tan extenso como el de los extends y los includes de los casos de uso.

Empecemos, debemos recordar siempre que una de las mayores criticas que recibe UML, es que ha logrado salvar muchas ambigedades... Pero no todas!!! aun quedan conceptos que se prestan a dobles interpretaciones, no se si este ser uno de ellos, pero por lo discutido parece que s. Por otro lado, podemos hacer un poco de historia, recordando que primero existi la asociacin, despus surge la Agregacin para representar un relacin estructural contenedor/contenido y luego como una "extensin" de esta ultima nace la Composicin.

Para explicar mi punto de vista voy a echar mano, al diagrama de clases que ya he utilizado en otro post y despus voy a poner el cdigo de la clase Persona, que es la que se lleva toda la carga de la discusin

El cdigo hace referencia, solo a este modelo, y es bien detallado, hasta con cosas innecesarias, o meramente tericas, pero lo que busco es fijar una posicin, concreta y definitiva, en el tema de las relaciones.

Algo importante a tener en cuenta, es que un objeto existe (digamos que esta vivo, pero esto no es tcnicamente correcto por que no es un hilo) mientras existe una variable de referencia que "apunte" (tampoco correcto, por que java no tiene punteros, je) a dicho objeto en memoria. Es decir que se convertir en elegible para ser borrado por el garbage collector, cuando no exista una variable que "apunte" a dicho objeto.

import java.util.LinkedList; import java.util.List; public class Persona { private String nombre; private String apellido; private List perfiles = new LinkedList(); private List lugaresFrecuentes = new LinkedList(); //Setters and Getters public String getNombre() {return nombre;} public void setNombre(String nombre) {this.nombre = nombre;} public String getApellido() {return apellido;} public void setApellido(String apellido) {this.apellido = apellido;} // OJO no confundir estos son solo setters y getters de las propiedades public List getPerfiles() {return perfiles;} public void setPerfiles(List perfiles) {this.perfiles = perfiles;} public List getLugaresFrecuentes() {return lugaresFrecuentes;} public void setLugaresFrecuentes(List lugaresFrecuentes) {this.lugaresFrecuentes = lugaresFrecuentes;} La clase comienza normalmente con la declaracin de las variables de instancia. Donde perfiles ylugaresFrecuentes son dos colecciones, pero tranquilamente podran ser arrays. que se transformarn en contenedores de elementos. Al ser propiedades tienen getters y setters (accessors y mutators), que nada tienen que ver con la agregacin y la composicin. Ahora veamos cuales son los mtodos que caracterizan a la relacin de AGREGACIN

public void agregarLugarFrecuenta(Lugar lugar){ if(!lugaresFrecuentes.contains(lugar)){ lugaresFrecuentes.add(lugar); } } public void removerLugarFrecuenta(Lugar lugar){ if(lugaresFrecuentes.contains(lugar)){ lugaresFrecuentes.remove(lugar); } } La primera caracterstica es que la clase contiene dos mtodos uno que agrega elementos a la coleccion y otro que los elimina de ella. He ac algo importante... los objetos son pasados por parametro, no han sido instanciados dentro del mtodo, es decir no hemos realizado el new del objeto. Ha "nacido" en cualquier otra parte y se lo hemos pasado por parmetro al mtodo para ser agregado a la lista lugaresFrecuentes. En otras palabras, el objeto Persona podria morir, y el objeto ahun podra mantener una referencia activa en alguna otra parte de nuestro codigo por lo tanto sus ciclos de vida no estran atados. No nace ni muere, dentro de la Persona. Cual es la Diferencia con la COMPOSICIN? public void agregarPerfil(){ Perfil p = new Perfil(); perfiles.add(p); } //sobrecarga public void agregarPerfil(String nombre){ Perfil p = new Perfil(nombre); perfiles.add(p); } public void removerPerfil(int index){ perfiles.remove(index); // aca lo quitamos de la lista } Bueno... la composicin tambin tiene los mtodos para agregar y borrar. Pero... "el new del objeto se realiza dentro del mtodo agregar" La instanciacin del objeto p se realiza dentro del mtodo agregar y la referencia no se devuelve (es void o boolean), la variable de referencia local va a dejar de existir una vez que el mtodo se termine de ejecutar, y el ciclo de vida de esa instancia en particular va a quedar atada a la lista, y por ende a la Persona. Una vez que el objeto Persona no se referencie ms, (o sea muera, aunque tcnicamente esto no es as) el objeto lista, quedar sin referencia, y por lo tantos sus elementos tambin. Adems como el mtodo no es esttico, se deber crear primero una instancia de Persona, para despus poder agregar un Perfil. Empezando as a "atar" el ciclo de vida de un Perfil, al de una Persona.

En cuanto al mtodo remover, no existe nada de extraordinario, simplemente quitamos un elemento de la lista.

Volvindonos Paranoicos de la Teora


Profundizando la paranoia y jugando con la teora; para que atemos definitivamente los ciclos de vida, la variable lugaresFrecuentes no debera ser una propiedad, y la clase Perfil debera ser una Inner Class. En el caso de la Inner class, hacemos esto para que se tenga que utilizar una instancia de la clase "Outer" para luego obtener una instancia de la clase Inner. Por ejemplo si en nuestro codigo, la clase Perfil, fuera una Inner class de la clase publica Persona (Se entiende no?, es decir que esta dentro del archivo Persona.java), para obtener una instancia de Perfil fuera de la clase persona tendramos que hacer: Persona persona = new Persona(); Persona.Perfil perfil = persona.new Perfil(); Y la clase Perfil existira mientras exista la instancia de persona. (ciclos de vida atados) En el caso de que la variable de instancia lugaresFrecuentes no debera tener getters y setters pblicos, esto se debe a que ningn otra clase, con excepcin de la clase Persona, debera tener la oportunidad de mantener una referencia viva a un objeto del contenedor. Y mucho menos obtener toda la Lista desde afuera! Un objeto Perfil, vive y muere con la Persona! Tambin de esto se pueden desprender otros delirios, como cuestiones de herencia y cosas as. Pero de nuevo, y no me voy a cansar de decirlo... esto es un extremo!!, es solo para conversar entre amigos, o vanagloriarse con algn profesor, no tiene nada de practico, ni de real, salvo para casos especficos.

Paranoia de la Paranoia
Crean que ya habamos terminado? aun se puede ser ms paranoico!!!! mucho se ha discutido sobre estos temas, y mucho fue paranoia terica. Lo siguiente, es algo que les llevar a sus amigos o profesor a decir, "...bueno pero eso ya es una locura": Sobreescribiremos el mtodo finalize() de la Clase Persona, que es un mtodo que todas las clases heredan de Object, y que se invoca justo antes de que un objeto sea borrado de la memoria por el garbage collector de java. public void finalize(){ for(Perfil p : perfiles){ p = null; } }

En el desreferenciamos cada uno de los elementos de la lista un segundo antes de que el objeto de tipo Persona desaparezca de la memoria, una milsima de segundo, o algo asi!!! atando definitivamente el nacimiento y muerte, el ciclo de vida, de un elemento contenido con su contenedor. Pero de nuevo!!! LA PARANOIA EN EL CDIGO NO ES BUENA!!! solo sirve en aquellas noches de borrachera entre programadores, en las cuales el boliche cerr y pinta quedarse en casa con amigos. Yo rescatara de todo este biri-biri aquello de "el new se realiza dentro del mtodo" y nada ms!!!

Das könnte Ihnen auch gefallen