Implementing associations

Finding out what associations are is pretty straightforward, what’s interesting is to make sure everybody in the project understand how to implement them on code. In this case, Java code. A couple of nice links on the matter are the ones in Java Ranch and Martin Fowler’s site.Averiguar qué es una asociación es bastante simple, lo que es interesante es asegurarse que todos en el proyecto entiendan como van a plasmar el modelo en código. En este caso, código Java. Un par de buenos links en este tema son el de Java Ranch y el sitio de Martin Fowler.

Quick review on associations.

Basically an association is relationship that enables classes to send messages to each other. Composition adds a life cycle relationship. Finally aggregation, a modeling placebo as Rumbaugh puts it, finds its ways on delegation and a definition before being used.

Reading the model.

On the model above we can see the three associations we’re going to define how to implement. Reading from left to right we first see the association between BillPrinter and Bill. Next we see a Customer aggregated to a Bill, a BillingAddress used to compose a Bill, and, a list of Item(s) aggregated to the same Bill.

Implementing the association.

To implement the arrow going from BillPrinter to Bill, it helps to notice in the model they are associated by the print method in BilPrinter. So this association seeks to send a printing message using a Bill as source of information. We could also have a print method without the Bill parameter and a setBill method, but it wouldn’t be this clear we mean to print the Bill.

class BillPrinter {
//attributes
private String serial;
private Location location;
//constructor
public BillPrinter() {
}
//printing a bill
public void print(Bill bill) {//here! here's where the model says "associate with Bill to accomplish this task".
System.out.println(bill.toString());
}
}

In Bill there are no mentions to BillPrinter. Bill is not aware is being used for printing purposes, and it doesn’t need to.

Implementing the aggregations and the composition.

Then, the white diamonds. They are trying to express that a the Customer and the list of Item(s) are part of the Bill to solve this use case, but they can go on with their lifes and have their own operations outside the Bill. They might be in the item’s list at the inventory or the sale campaign for the top 50 customers in the CRM.

class Bill {
// aggregation attributes
private Customer customer;
private List items;
//composition attribute
private AddressInfo address;
//constructor
public(Customer customer, List items) {
this.customer = customer; //Bill uses a Customer that already exists
this.items = items; //the same for the Item(s), they already exist
address = new AddressInfo(this); //here! Bill creates an AddressInfo for its personal use
}
//getters
public Customer getCustomer() {
return customer;
}
public List getItems() {
return customer;
}
public AddressInfo getAddress() {
return customer;
}
//but NO setters!
}

Aggregation attributes already exist, but Bill needs them to be a full object, so their references are taken in the constructor, so we don’t risk we find ourselves with a Bill without a Customer. The same goes for the list of Item(s).

In the other hand, an AddressInfo doesn’t exist as an individual entity but helps to encapsulate a set of attributes that might change over time. So the AddressInfo lives as long as the Bill has a reference, otherwise they both go together to the garbage collector.

Agreement.

The whole point of these efforts are to agree what a model will mean. You might decide in your enterprise these implementations are not good for you and changed them. But do it before modeling and then communicate it, so everybody will be modeling something that everybody will be able to implement in a standard way. This means clear and useful models.

Revisión rápida de asociaciones.

Básicamente una asociación es una relación que permite el envío de mensajes de una clase a otra. La composición agrega una dependencia en el ciclo de vida. Finalmente la agregación, presentado por Rumbaugh como un placebo para modelado, funciona por medio de delegación y definición previa.

Leyendo el modelo.

En el modelo de arriba podemos ver las tres asociaciones que estamos por definir su implementación. Leyendo de izquierda a derecha vemos primero la asociación entre BillPrinter (ImpresorFactura) y Bill (Factura). A continuación vemos un Customer (Cliente) agregado a Bill, una BillingAddress (DireccionFacturacion) utilizada para componer una Bill, y, una lista de Item(s) agregada a la misma Bill.

Implementación de la asociación.

Para implementar la flecha que va desde BillPrinter to Bill, nos ayuda notar en el modelo que se encuentran asociados por el método print (imprimir) en BilPrinter. Por tanto esta asociación busca enviar un mensaje de impresión utilizando a Bill como fuente de informacion. También podríamos haber modelado un método print sin el parámetro Bill y añadir un metodo setBill, pero no hubiera sido tan claro que lo que buscamos es imprimir una Bill.

class BillPrinter {

//atributos

private String serial;

private Location location;

//constructor

public BillPrinter() {

}

//imprimiendo una factura

public void print(Bill bill) {//aquí! aquí es donde el modelo dice “asociarse con Bill para ejecutar esta tarea”.

System.out.println(bill.toString());

}

}

En Bill no se hace referencia alguna a BillPrinter. Bill no se entera nunca que es utilizada con propósitos de impresión, y no lo necesita tampoco.

Implementación de las agregaciones y la composición.

Luego los diamantes blancos. Estos están tratando de expresar que Customer y una lista de Item(s) son parte de una Bill para la solución de este caso de uso, pero que pueden continuar con sus vida y tener sus operaciones fuera de la Bill. Podrían estar en la lista de items del inventario o en la campaña de ofertas para los 50 mejores clientes del CRM.

class Bill {

// atributos de la agregación

private Customer customer;

private List items;

//atributos de la composición

private AddressInfo address;

//constructor

public(Customer customer, List items) {

this.customer = customer; //Bill utiliza Customer que ya existe

this.items = items; //lo mismo para Item(s), ya existen

address = new AddressInfo(this); //aquí! Bill crea una AddressInfo para su uso personal

}

//getters

public Customer getCustomer() {

return customer;

}

public List getItems() {

return customer;

}

public AddressInfo getAddress() {

return customer;

}

//pero NO hay setters!

}

Los atributos de la agregación ya existen fuera de Bill, pero esta lo necesita para ser un objeto completo, por eso las referencias son obtenidas en el constructor, y asi evitamos el riesgo de tener una Bill sin Customer. Lo mismo sucede con la lista de Item(s).

Por otro lado, una AddressInfo no existe como una entidad individual sino encapsula un conjunto de atributos que pueden cambiar con el tiempo. Por tanto AddressInfo vive mientras exista una referencia hacia Bill, caso contrario las dos terminaran en el recolector de basura.

Acuerdo.

El objetivo de todo esto es que se llegue a un acuerdo sobre el significado que tendrá el modelo. Tu puedes decidir que estas interpretaciones no son buenas para tu empresa y decidas cambiarlas. Pero hazlo antes de comenzar a modelar y luego comunícalo, de manera todos estarán modelando algo que todos saben como implementar. Esto significa modelos claros y útiles.

Advertisements

One response to “Implementing associations

  1. keep up the good work

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s