Universidad Nacional de Trujillo Ingeniería de Sistemas
Tecnología de la Programación I Identificación de Clases
IDENTIFICACIÓN DE CLASES Los diagramas de clases de UML se utilizan para documentar la estructura estática del sistema; esto es, qué clases hay y cómo están relacionadas.
La técnica del diagrama de clase se ha vuelto medular en los métodos orientados a objetos. Virtualmente todos los métodos han incluido alguna variación de esta técnica. El diagrama de clase describe los tipos de objetos que hay en el sistema y las diversas clases de relaciones estáticas que existen entre ellos. También muestra los atributos y operaciones (métodos) de una clase y las restricciones a las que se ven sujetos, según la forma en que se conecten los objetos. 1.
Clases. Una clase describe un conjunto con un rol o roles equivalentes en un sistema. Los objetos y su división en clases a menudo derivan de una de las siguientes fuentes: Cosas tangibles o “del mundo real”: libro, copia, curso. Roles: socio, estudiante, director de estudios. Eventos: llegada, salida, petición. Interacciones: encuentro, intersección. Estas categorías se solapan, y las dos primeras son fuentes de objetos y de clases mucho más comunes que las dos últimas. Por el contrario, si se han identificado objetos que entran dentro de las dos primeras categorías, las otras dos pueden ayudar a encontrar y nombrar asociaciones entre ellos. Es importante recordar que los objetos son realmente cosas dentro de un programa de computador; que cuando se habla sobre “libros” y “copias”, por ejemplo, realmente nos referimos a la representación de estas cosas dentro de nuestro sistema. Las consecuencias de esto son que hay que tener cuidado: De no almacenar información que es definitivamente irrelevante para nuestro sistema. De no perder la visión del hecho de que ¡los objetos son el sistema! El último punto es particularmente interesante. Un error clásico es inventarse una clase, a menudo llamada [Cualquier_cosa]System, que implementa todo el comportamiento interesante del sistema. Pero en Orientación a Objetos todo el negocio es el sistema; ¡este es el tema! Es fácil dejarse llevar hacia un diseño monolítico donde hay un único objeto que conoce y hace todo. Esto está mal porque tales diseños son muy difíciles de mantener: tienden a tener presunciones sobre cómo será utilizado el sistema. 1.1. Identificación de objetos y clases. La construcción de un modelo de clases incluye la identificación de las clases que deberían existir en nuestro sistema: ésta es una parte fundamental del trabajo de diseñar un sistema orientado a objetos. Hay dos objetivos que se pretenden alcanzar: Construir, lo más rápido y barato posible, un sistema que satisfaga nuestros requisitos actuales. Para ello: “Cada comportamiento que requiera el sistema debe ser proporcionado por los objetos de las clases que elijamos”. Construir un sistema que sea fácil de mantener y adaptar a futuros requisitos. Para lograrlo: “Un buen modelo de clases está formado por módulos encapsulados, con acoplamiento débil (pocas dependencias entre módulos) y cohesión fuerte (los
Ing. Zoraida Yanet Vidal Melgarejo, Mg.
-1-
Universidad Nacional de Trujillo Ingeniería de Sistemas
Tecnología de la Programación I Identificación de Clases
módulos poseen interfaces que proporcionan al desarrollador lo necesario que debe conocer para utilizarlos)”. En la práctica, es probable que al construir un modelo de clases lo haga correctamente la primera vez. La colección de clases en su modelo de diseño, es una de las cosas que probablemente cambiará a los largo y dentro de las iteraciones de desarrollo. Normalmente identificará primero y más fácilmente las clases más importantes de los objetos del dominio, es decir, aquellas que pertenecen de manera obvia al problema, en vez de aquellas que se introducen para resolverlo; las otras clases, que se corresponden con menos claridad con los objetos del dominio, son más difíciles de identificar con seguridad. 1.2. Técnica: identificación de nombres. Se procede en dos etapas: 1. Identifica las clases candidatas seleccionando todos los nombres y locuciones nominales de la especificación de requisitos del sistema (considérelos en forma singular y no incluya frases que contengan “o” como candidatas). 2. Descarte las candidatas que son inapropiadas por cualquier razón, renombrando las clases restantes si es necesario. Las razones por las que se podría decidir que una clase candidata es inapropiada incluyen que es: Redundante, donde a la misma clase se le ha dado más de un nombre. Es, sin embargo importante recordar que los objetos parecidos no tienen que se completamente iguales: una de las cosas que hay que decidir es si las clases son los suficientemente diferentes para considerarlas clases distintas. Por ejemplo, se incluyen aquí pares como “préstamo” y “préstamo a corto plazo”: son diferentes, pero probablemente sólo en los valores de los atributos. Elija un nombre para la clase que abarque todas las descripciones que quiera que incluya. Impreciso, donde no se puede indicar de forma no ambigua lo que significa un nombre. Obviamente hay que eliminar la ambigüedad antes de poder decir que se trata de una clase. Un evento u operación, donde el nombre hace referencia a algo que se hace para, por o en el sistema. A veces tales cosas están bien modeladas en una clase, pero no es lo normal. Pregúntese si la instancia del evento u operación tiene estado, comportamiento e identidad. Si no, descártelo. El estado de un objeto lo constituyen todos los datos (atributos) que encapsula en un momento determinado. El comportamiento es la manera como actúa y reacciona un objeto, en función de sus cambios de estado y el paso de mensajes. La identidad es que a los objetos se les hace referencia por un nombre (el valor de una variable en un programa cliente) pero el nombre del objeto no es lo mismo que el objeto, porque un mismo objeto puede tener varios nombres diferentes. Metalenguaje, donde el nombre forma parte de la manera en que se definen las cosas. Se utilizan los nombres requisitos y sistema, por ejemplo, como parte del lenguaje de modelado, en vez de representar objetos en el dominio del problema. Fuera del alcance del sistema, donde el nombre es relevante para describir cómo funciona el sistema pero que no hace referencia a algo. Un atributo, donde está claro que un nombre hace referencia a algo sencillo, sin un comportamiento interesante, que es un atributo de otra clase. En general, si se duda si mantener una clase, una buena práctica sería mantener dos listas, una con los candidatos más firmes y otra con los más dudosos. Con ello se evita perder información mientras se está distinguiendo todavía las cosas de las que se esté seguro, de las cosas que tienen que ser fijadas todavía. Ing. Zoraida Yanet Vidal Melgarejo, Mg.
-2-
Universidad Nacional de Trujillo Ingeniería de Sistemas
Tecnología de la Programación I Identificación de Clases
1.3. Representación gráfica de una clase empleando la notación UML. Una clase se representa con una figura rectangular dividida en tres partes: Parte superior: el nombre de la clase. Ejemplo: Libro. Parte media: los atributos de la clase señalando alcance, nombre y tipo. Ejemplo: + autor : String Parte inferior: los métodos de la clase señalando lista de argumentos y tipo de retorno. Ejemplo: + setAutor (autor : String) : void
Libro - autor : String - titulo : String - cantidadLibros : int + + + + + + + +
Libro() Libro(autor:String, titulo:String) setAutor(autor:String) : void getAutor() : String setTitulo(titulo:String) : void getTitulo() : String getNumeroEjemplares() : int toString() : String
La implementación del diagrama de la clase Libro es la siguiente: public class Libro { private String autor; private String titulo; private static int cantidadLibros; public Libro() { this("NA","NT"); } public Libro(String autor, String titulo) { setAutor(autor); setTitulo(titulo); ++cantidadLibros; } public void setAutor(String autor) { this.autor = autor; } public String getAutor() { return autor; } public void setTitulo(String titulo) { this.titulo = titulo; } public String getTitulo() { return titulo; } public static void getCantidadLibros() { return cantidadLibros; } public String toString() { return "Datos de libro: " + titulo + "\n" + autor; } }
Ing. Zoraida Yanet Vidal Melgarejo, Mg.
-3-
Universidad Nacional de Trujillo Ingeniería de Sistemas 2.
Tecnología de la Programación I Identificación de Clases
Atributos y métodos. El sistema que se construye consistirá en una colección de objetos, que interactúan para completar los requisitos del sistema. Es necesario identificar los atributos y los métodos que cada clase debería tener. Algunos serán obvios; otros aparecerán cuando se consideren las responsabilidades de los objetos y las interacciones entre ellos. 2.1. Atributos. 1.
Atributos de clase: son aquellos que representan valores comunes a todas las instancias de una clase. Pueden tener un valor inicial. Por ejemplo: private static double promedioEdades; private static int numeroAlumnos = 0;
2.
Atributos de instancia: son aquellos que representan valores propios de un solo objeto que lo diferencia de otros elementos de su misma clase. Pueden tener un valor por defecto. Por ejemplo: private String nombre; private int numeroPuertas = 4;
3.
Constantes: son definidas por el modificador final y representan valores inmutables en tiempo y espacio. El nombre de las constantes debe escribirse totalmente en mayúsculas. Por ejemplo: public final int MAX = 20; public static final double PI = 3.1415;
2.2. Métodos. 1. Métodos de clase: son acciones que no requieren de un objeto específico para su realización. Los métodos de clase sólo tienen acceso a los atributos de clase. Por ejemplo: public static int sumar(int x, int b) { int suma = 0; suma = x + y; return suma; } 2. Métodos de instancia: son acciones que requieren de un objeto específico. Los métodos de instancia tienen acceso a todos los miembros de la clase, tanto atributos de clase como atributos de instancia. Por ejemplo: public String getNombre( ) { return nombre; } 3.
Diagrama de Clases. El Diagrama de Clase es el diagrama principal de análisis y diseño de un sistema. En él se especifica la estructura de clases del sistema, con relaciones entre clases y estructuras de herencia. Su objetivo varía en análisis y diseño:
Durante el análisis del sistema, el diagrama se desarrolla buscando una solución ideal. Durante el diseño, se usa el mismo diagrama, y se modifica para satisfacer los detalles de las implementaciones.
Ing. Zoraida Yanet Vidal Melgarejo, Mg.
-4-
Universidad Nacional de Trujillo Ingeniería de Sistemas 4.
Tecnología de la Programación I Identificación de Clases
Relaciones. Una relación en un diagrama de clases, se representa mediante una línea que une dos o más clases. Las relaciones más comunes entre las clases presentes en un diagrama pueden ser: asociación (binaria o n-aria), agregación, composición, generalización y dependencia. Relación
1
Curso
Multiplicidad
Se imparte
+curso
1..*
Clase
+clases
Rol
El Rol describe la semántica que tiene la relación en el sentido indicado. La Multiplicidad indica la cardinalidad de la relación, y puede ser: 1 Uno y sólo uno 0..1 Cero o uno M..N Desde M hasta N * Muchos n Exactamente n 0..* Cero o muchos 1..* Uno o muchos (al menos uno).
A continuación se muestran los diagramas de los diferentes tipos de asociaciones y se acompañan de parte de la implementación de las clases que forman parte de la asociación (la implementación de cada clase deberá ser completada tomando en consideración los atributos y métodos propios de cada una de las clases). 4.1. Asociación Binaria.
Matricula
1
Consta De
*
-matricula
public class Matricula { private Curso cursos[];
public class Curso { private Matricula matricula;
public Matricula(int n) { cursos = new Curso[n]; } ... }
Ing. Zoraida Yanet Vidal Melgarejo, Mg.
Curso
-cursos
public Curso(Matricula matricula) { this.matricula = matricula; } ... }
-5-
Universidad Nacional de Trujillo Ingeniería de Sistemas
Tecnología de la Programación I Identificación de Clases
4.2. Asociación Reflexiva.
Trabajador
public class Trabajador { private Trabajador jefe; private Trabajador subordinado[];
-subordinado 0..*
public Trabajador(Trabajador jefe, int n) { this.jefe = jefe; subordinado = new Trabajador[n]; } ...
Supervisor De
-jefe 0..1
}
4.3. Asociación n-aria. Contenido En
1
Artículo
-articulo
*
OrdenCompra
-ordenC
ItemOC
public class Articulo {
public class OrdenCompra { private ItemOC ítems[];
public Articulo() { ... } ...
public OrdenCompra() { ... } ...
}
class ItemOC { private Articulo articulo; public ItemOC(Articulo articulo) { this.articulo = articulo; } ... } }
4.4. Asociación de Agregación. Automovil
1
Es Accesorio De
0..1
-automovil
Radio
-radio
public class Automovil {
public class Radio {
private Radio radio;
public Radio() { ... } ...
public Automovil(Radio radio) { this.radio = radio; } ...
}
}
Ing. Zoraida Yanet Vidal Melgarejo, Mg.
-6-
Universidad César Vallejo Ingeniería de Sistemas
Programación Orientada a Objetos Identificación de Clases
4.5. Asociación de Composición. public class Automovil { private Motor motor;
Automovil
-automovil
public Automovil(Motor motor) { this.motor = motor; } ...
1 Es Parte De
-motor
0
public final class Motor { public Motor() { ... } }
Motor
}
4.6. Asociación de Generalización / Especialización. Publicacion
Generalización
Especialización
Libro
public class Publicacion {
public class Libro extends Publicacion {
... public Publicacion() { super(); ... } ...
public Publicacion() { ... } ... }
}
4.7. Asociación de Dependencia. Potencia
Math pow(a:Double, b:Double)
public class Potencia { public static void main(String [] args) { double x =5, y=2, z; z = Math.pow(x,y); System.out.println(“El cuadrado de 5 es: “ + z); } }
Ing. Zoraida Yanet Vidal Melgarejo, Mg.
-7-