El diagrama de clases nos permite saber la estructura estática de nuestro programa, es decir, qué datos se guardan dónde. Pero si no sabemos convertir este diagrama a código no nos sirve de nada, por lo que hay que ver algunas reglas al convertir del diagrama de clases a las clases en sí.
Primero que nada, vamos a tomar en cuenta que en nuestro diagrama de clases tuviéramos una clase sin asociaciones como la siguiente:
Primero que nada creamos una clase con el nombre de la clase:
public class ClassA { }
Una vez que hicimos esto vamos a agregar los atributos. Como en este caso todos los atributos son privados vamos a ponerlos de esta manera, pero si fueran públicos o protegidos tendríamos que cambiar la declaración de manera acorde:
public class ClassA { private int id; private String name; }
Ahora vamos a declarar el constructor de la clase, por lo general esto es cuestión de las necesidades del programa y es una decisión que debe realizar el programador, pero digamos que vamos a utilizar un constructor que recibe todos los parámetros y un constructor por omisión (como mínimo las clases deben tener un constructor por omisión).
public class ClassA { private int id; private String name; public ClassA() { this.id = -1; this.name = ""; } public ClassA(int id, String name) { this.id = id; this.name = name; } }
Después debemos crear el método que está declarado en la clase, tomando en cuenta los parámetros y los tipos que se declararon:
public class ClassA { // [...] public int doSomething(long x, long y) { return 0; } }
Una vez que ya tenemos todo esto debemos seleccionar qué parámetros pueden ser cambiados por el mundo exterior. En este caso digamos que el id es un identificador secreto que nos sirve en la base de datos, mientras que el nombre sí es público, tomando esto en cuenta debemos crear getters y setters sólo para el atributo name.
public class ClassA { // [...] public String getName() { return name; } public void setName(String name) { this.name = name; } }
Y con eso ya tenemos la clase. Casi todas las clases que declaremos van a construirse de una manera similar, los cambios vienen cuando nuestra estructura es más complicada.
Imaginemos una clase que utiliza constantes para establecer su estado como se ve en el siguiente diseño:
Esto puede traducirse de dos maneras, mediante variables y mediante enumeraciones.
La primera es un poco más de talacha, pero es más sencilla y se usa cuando los valores numéricos que tienen las constantes nos sirven para algo (por ejemplo para calcular la suma, o si queremos poner más de un tipo) o cuando no queremos complicarnos con enumeraciones. Esta manera es declarar varias variables numéricas y utilizarlas como constantes al declarar el tipo de la siguiente manera:
public class ClassA { public static final int STATE_NEW = 0; public static final int STATE_OLD = 1; private int id; private String name; private int state; public ClassA() { this.id = -1; this.name = ""; // state toma el valor de 0, por la constante state = STATE_NEW; } // [...] }
Veamos un poco más a fondo la declaración de las constatnes:
public significa que cualquier clase las va a poder verstatic significa que la variable le pertenece a la clase y no a las instancias de la clasefinal significa que es una constante y su valor no puede cambiar en tiempo de ejecuciónLa otra manera de crear constantes es hacer una enumeración, un tipo especial de Java que nos permite enumerar varios valores y agruparlos en algo similar a una clase. Esto se puede hacer de la siguiente manera:
public enum State { NEW, OLD } private int id; private String name; /** state va a ser de tipo State, es decir, va a depender de la enumeracion */ private State state; public ClassA() { this.id = -1; this.name = ""; // state toma el valor NEW de la enumeracion State state = State.NEW; } // [...] }
También podemos tener que convertir una clase con asociaciones a otra clase, para esto tomemos en cuenta el siguiente diagrama:
Primero que nada vamos a necesitar crear ClassB (que en este caso sería una clase vacía) de la siguiente manera:
public class ClassB { }
Una vez que tenemos esta clase nos tenemos que fijar quién contiene a quién, y en este caso nos damos cuenta de que ClassA contiene a ClassB porque ClassA es la que tiene el rombo de la asociación. Aquí es importante tomar en cuenta que en el diseño debemos seleccionar la mejor estructura de datos, en este caso por simplicidad voy a utilizar un [ArrayList]:
public class ClassA { private int id; private String name; // Declaro la lista que va a la otra clase private ArrayList<ClassB> others; public ClassA() { this.id = -1; this.name = ""; others = new ArrayList<ClassB>(); } // [...] }
Pero también podría hacerlo con arreglos:
public class ClassA { private int id; private String name; private ClassB others[]; public ClassA() { this.id = -1; this.name = ""; others = new ClassB[50]; } // [...] }
Algunas veces también es necesario construir una asociación con una clase intermedia de la siguiente manera:
Este tipo de asociaciones se dan cuando las dos clases dependen de la otra, por ejemplo cuando tenemos una lista de alumnos y una lista de exámenes y los varios alumnos pueden contestar varios exámenes. En estos casos no es fácil decir hacia dónde iría la asociación, por lo que se introduce la clase intermedia. Primero que nada vamos a crear la clase intermedia:
public class AssociationClass { }
En esta clase intermedia vamos a incluir una referencia a cada una de las clases que se encuentran asociadas (en este caso ClassA y ClassB), además vamos a crear constructores y vamos a crear getters y setters:
public class AssociationClass { private ClassA a; private ClassB b; public AssociationClass() { this.a = null; this.b = null; } public AssociationClass(ClassA a, ClassB b) { this.a = a; this.b = b; } public ClassA getA() { return a; } public void setA(ClassA a) { this.a = a; } public ClassB getB() { return b; } public void setB(ClassB b) { this.b = b; } }