Logo Studenta

UPSAM _ Grado en Ingeniería a Informática _ Programación Orientada a Objetos y Aplicaciones _ Aplicacion

Esta es una vista previa del archivo. Inicie sesión para ver el archivo original

Aplicaciones 2015-2016 Campus/Anexo JDBC v2.pdf
1 
 
Asignatura .Programación de Aplicaciones 
 
 
 
 
 
 
 
 
 
 
Anexo .JDBC Java DataBase Conectivity 
 
 
 
2 
 
Índice de contenidos 
 
1. Introducción JDBC ................................................................................................................. 3 
2. Arquitecturas JDBC ................................................................................................................ 4 
3. Abrir la conexión con la base de datos ................................................................................. 5 
3.1. Cargar el Driver.............................................................................................................. 5 
3.2. Obtener una conexión ................................................................................................... 5 
3.3. Ejecutar una sentencia SQL ............................................................................................... 6 
3.4. Procesar los resultados de una consulta ........................................................................... 7 
4. Sentencias precompiladas (Prepared Statement)................................................................. 8 
5. Procedimientos almacenados ............................................................................................... 8 
6. Transacciones ........................................................................................................................ 8 
7. Bibliográfica ........................................................................................................................... 9 
 
 
3 
 
 
1. Introducción JDBC 
La API JDBC (Java DataBase Conectivity) permite acceder a cualquier clase de base 
de datos relacional desde el lenguaje Java. 
La siguiente figura muestra una analogía para entender mejor el concepto de JDBC 
 
Esencialmente una interacción con JDBC consta de los siguientes pasos 
1. Abrir una conexión con la base de datos. 
2. Enviar una sentencia SQL al gestor de base de datos. 
3. Recuperar y procesar los resultados devueltos como resultado de la ejecución del 
comando SQL. 
El siguiente código muestra un ejemplo de estos tres pasos 
4. Class.forName("com.mysql.jdbc.Driver").newInstance(); 
5. Connection con = DriverManager.getConnection 
6. ( " jdbc:mysql://localhost/laboratorio ", "root","root"); 
7. 
8. Statement stmt = con.createStatement(); 
9. ResultSet rs = stmt.executeQuery("select * from usuarios "); 
10. while (rs.next()) { 
11. int id = rs.getInt("Id"); 
12. String pass = rs.getString("password"); 
13. } 
 
 La línea 4 carga el driver para interactuar con una base de datos MySQL 
 La línea 5 establece una conexión con la base de datos MySQL 
 La línea 8 crea una sentencia SQL sobre la conexión 
4 
 
 Línea 9 envía la sentencia al SGBD para su ejecución , el resultado de la 
sentencia se devuelve en forma de ResultSet 
 Las líneas 10,11,12,13 procesan cada una de la filas de la tabla devuelta en el 
objeto ResultSet 
 
2. Arquitecturas JDBC 
Modelos de dos y tres capas 
JDBC soporta modelos de dos y tres capas para el acceso a base de datos 
 En el modelo de dos capas la aplicación Java interactúa con la base de datos a 
través de un controlador cargado en la propia aplicación .La base de datos puede 
residie en la misma máquina o en una máquina en red ( configuración 
cliente/servidor). 
 
Figura 2: arquitectura de acceso a datos de dos capas. 
 En el modelo de tres capas la aplicación Java interactúa con la base de datos a 
través de una capa de servicio intermedia, ubicada en un servidor que optimiza 
este tipo de interacción. Esto tiene la ventaja de desacoplar al cliente de los 
detalles del gestor de base de datos. Esta arquitectura permite la implementación 
de transacciones distribuidas, fuentes desconectadas y gestión de pool de 
conexiones incrementado el rendimiento. 
 
 
Figura 3: arquitectura de acceso a datos de tres capas. 
 
5 
 
 
 
3. Abrir la conexión con la Base de Datos 
 
3.1. Cargar el Driver 
Sólo implica una línea de código. Si, por ejemplo, queremos utilizar el driver de 
MySQL seria de la siguiente forma: 
 Class.forName("com.mysql.jdbc.Driver ").newInstance(); 
Una vez cargado el driver, es posible establecer una conexión con un controlador de 
base de datos. 
3.2. Obtener una conexión 
Una vez cargado el Driver de la base de datos, el segundo paso para establecer una 
conexión es tener el driver apropiado conectado al controlador de base de datos. La 
siguiente línea de código ilustra la idea general para realizar esto. 
Connection con = DriverManager.getConnection 
 ( " jdbc:mysql://localhost/laboratorio ", "root","root"); 
Dónde: 
 jdbc:mysql indica que se va usar un driver nativo para mysql .Si estamos 
utilizando un puente JDBC desarrollado por una tercera parte, la documentación 
nos dirá el subprotocolo a utilizar, es decir, qué poner después de jdbc: en la 
URL 
 //localhost indica la máquina donde reside el sistema gestor de base de datos.En 
este ejemplo es la máquina local pero en caso de ser remota irá definida con una 
IP 
 /laboratorio indica el nombre de la base de datos a la cual se desea conectar 
 root,root indica las credenciales ( nombre y contraseña) que se usarán en la 
conexión. 
La clase DriverManager, como su nombre indica, maneja todos los detalles del 
establecimiento de la conexión. A menos que estemos escribiendo un driver, 
posiblemente nunca utilizaremos ningún método del interface Driver, y el único método 
de DriverManager que realmente necesitaremos conocer es 
DriverManager.getConnection.(…) 
La conexión devuelta por el método DriverManager.getConnection es una conexión 
abierta que se puede utilizar para crear sentencias JDBC que pasen nuestras sentencias 
SQL al controlador de la base de datos. 
6 
 
3.3. Ejecutar una sentencia SQL 
Las sentencias SQL de manipulación de datos (DML) que se pueden ejecutar sobre una 
base de datos son : 
 SELECT selección de filas 
 INSERT inserción de filas 
 UPDATE actualización de filas 
 DELETE borrado de filas 
La API JDBC permite enviar cualquiera de estas sentencias a través de la clase 
Statement. A continuación se muestra la forma general de crear una sentencia 
Statement stmt = con.createStatement(); 
 
Donde con es un objeto de tipo Connection 
Statement abstrae el concepto de comando SQL y siempre debe estar asociado a una 
conexión activa 
A continuación simplemente ejecutamos la sentencia SQL( en este caso una sentencia 
SEECT) de la siguiente forma: 
ResultSet rs = stmt.executeQuery("select * from usuarios "); 
 
Donde el objeto rs es un objeto ResultSet que representa a la tabla que se obtiene 
como resultado de ejecutar la sentencia SQL. 
El objeto Statement admite la ejecución de sentencias SQL a través de los siguientes 
métodos 
 ResultSet executeQuery(comando_SQL) 
o Devuelve una tabla representada por un ResultSet 
o Se utiliza para la sentencia SELECT. 
 int executeUpdate(comando_SQL) 
o Devuelve un entero indicando el número de filas afectadas por la 
sentencia. 
o Se usa para sentencias UPDATE,DELETE,INSERT,CREATE 
Ejemplo de sentencias de modificación de datos 
 int n=stmt.executeUpdate(“update usuarios set id=2 where 
id=12”); 
 smt.executeUpdate(“INSERT INTO USUARIOS(Id,nombre,contraseña) 
VALUES (234,”root”,”root”)”) 
 
7 
 
3.4. Procesar los resultados de una consulta 
JDBC devuelve los resultados de una sentencia SELECT en un objeto ResultSet, por 
eso si se ha ejecutado una sentencia SELECT el resultado será un objeto de tipo 
ResultSet que podrá ser recorrido fila por fila y en sentido hacia delante solamente. 
while (rs.next())
{ 
 int id = rs.getInt("Id"); 
 String pass = rs.getString("password"); 
 } 
 
Donde rs es un objeto de tipo ResultSet y para obtener el valor de columna 
(“nombre”) se utiliza el método getXX donde XX indica el tipo de la columna con ese 
“nombre” 
Los métodos getXXX del tipo apropiado se utilizan para recuperar el valor de cada 
columna. Por ejemplo, la primera columna de cada fila de rs es Id, que almacena un 
valor del tipo INTEGER de SQL. El método para recuperar un valor INTEGER es get 
Int sin embargo para un tipo VARCHAR sería getString. 
La siguiente tabla muestra la correspondencia de los métodos de acceso sobre tipos java 
y su equivalencia de tipos SQL 
 
Otra cuestión importante es que el objeto ReseultSet es de sólo lectura, lo que 
impide realizar cualquier modificación sobre los datos que tiene. 
8 
 
Si la sentencia ejecutada es de modificación de datos, el resultado devuelto por el 
JDBC será el número de filas afectadas 
int n=stmt.execute(“update usuarios set id=2 where id=12”); 
if (n==0) { System.out.println(“Error en la actualización”)}; 
 
4. Sentencias precompiladas (Prepared Statement) 
Algunas veces es más eficiente tener la sentencia SQL precompilada en el gestor de 
base de datos y simplemente invocarla con nuevos parámetros. Esto es útil cuando 
queremos ejecutar repetidamente la misma sentencia SQL con solamente cambios en los 
parámetros. Para ello se utiliza el objeto PreparedStatement en lugar de Statement 
PreparedStatement stmtPre = con.prepareStatement( "select * from 
usuarios where id=?"); 
Donde el carácter ? indica que es un parámetro de la consulta 
Ahora necesitamos proporciona un valor al parámetro indicado en la consulta 
 stmtPre.setString(1,”12”); 
Donde 1 indica el número de parámetro y “12” el valor del parámetro. 
 
5. Procedimientos almacenados 
JDBC permite crear y llamar a procedimientos almacenados en el sistema gestor de base 
de datos. 
Para realizar esto primero creamos el procedimiento 
Statement stmt =con.createStatement(); 
Smt.executeUpdate("create procedure MOSTRAR_USUARIOS " + "as " + 
"select * from usuarios”); 
Ahora el procedimiento ya estaría creado, para llamarlo debemos usar un objeto 
Callablestatement 
CallableStatement cs = con.prepareCall("{call MOSTRAR_USUARIOS}"); 
ResultSet rs = cs.executeQuery(); 
6. Transacciones 
Cuando se crea una conexión por defecto se configura en modo auto confirmación ( 
auto-commit). Esto significa que cada sentencia SQL que se lance sobre esa conexión es 
9 
 
tratada como una transacción única y será automáticamente confirmada y acometida 
justo después de ser ejecutada. 
Establecer la confirmación de forma explicita 
La forma de permitir que dos o más sentencia sean agrupadas en una transacción es 
desactivar el modo auto-confirmación ( auto commit) 
 A continuación se muestra la instrucción que realiza esto, donde con es una conexión 
activa. 
con.setAutoCommit(false); 
Una vez que se ha desactivado la auto-confirmación, no se confirmará ninguna 
sentencia SQL hasta que no llamemos explícitamente al método commit ( confirmar). 
Todas las sentencias ejecutadas después de la anterior llamada al método commit serán 
incluidas en la transacción actual. El siguiente código, en el que con es una conexión 
activa, ilustra una transacción. 
con.setAutoCommit(false); 
PreparedStatement updateSales = con.prepareStatement( "UPDATE COFFEES 
SET SALES = ? WHERE COF_NAME LIKE ?"); 
updateSales.setInt(1, 50); 
updateSales.setString(2, "Colombian"); 
updateSales.executeUpdate(); 
PreparedStatement updateTotal = con.prepareStatement( "UPDATE COFFEES 
SET TOTAL = TOTAL + ? WHERE COF_NAME LIKE ?"); 
updateTotal.setInt(1, 50); 
updateTotal.setString(2, "Colombian"); 
updateTotal.executeUpdate(); 
con.commit(); 
con.setAutoCommit(true); 
 
7. Bibliográfica 
 Trail JDBC(TM) Database Access (The Java™ Tutorials) 
 
 
Aplicaciones 2015-2016 Campus/DOCUMENTO DE TRABAJO N3.pdf
Programación de aplicaciones (15/04/2013) 
 
Detalle de la aplicación de patrón Singleton sobre un contenedor de entidades 
(ContenedorClientes) en el proyecto. 
public class ContenedorClientesSingleton { 
 
 private LinkedList<Cliente> coleccionElementos; 
 
 private static ContenedorClientesSingleton _instancia; 
private ContenedorClientesSingleton(){ 
coleccionElementos = new LinkedList(); 
} 
public static ContenedorClientesSingleton getInstancia(){ 
if (_instancia == null) { 
 //Si la instancia no se ha creado crearla 
 _instancia = new ContenedorClientesSingleton(); 
 } 
 return _instancia; 
} 
public Cliente obetenerCliente( String id){…} 
public bool borrarElementos (){…} 
public bool grabarElementos (){…} 
 
Detalle de utilización de una clase Singleton anterior en el proyecto 
ContenedorClientesSingleton contenedorCli= ContenedorClientesSingleton.getInstancia(); 
 
 
Caso de Uso : Grabar Elementos 
Este caso conllevará en nuestro caso la aplicación del patrón ADO (Active Domain Object) 
visto en clase. Para ver el detalle de implementación del patrón se muestra una 
simplificación de clase Customer ( del libro Data Access Patterns: Database Interactions in 
Object-Oriented Applications) que el alumno deberá adaptar al proyecto. 
Nota :En negrita se muestra las características relevantes respecto al patrón 
public class Customer { 
 
 // SQL statements for data access. 
 
 private static final String INSERT 
 = "INSERT INTO CUSTOMERS " 
 + "(LAST, FIRST, ADDRESS, CITY, STATE, COUNTRY, " 
 + "ZIP, CUSTID) VALUES(?, ?, ?, ?, ?, ?, ?, ?)"; 
 
 private static final String UPDATE 
 = "UPDATE CUSTOMERS SET LAST = ?, FIRST = ?, " 
 + "ADDRESS = ?, CITY = ?, STATE = ?, COUNTRY = ?, " 
 + "ZIP = ? WHERE CUSTID = ?"; 
 
 // The customer's data attributes. 
 private int id; 
 private String name; 
 private Address address; 
 
 // Indicates whether the data in the active domain 
 // object matches that in the database. 
 private boolean saved = false; 
 
 /** 
 Constructs a Customer object. This constructor is 
 intended for application code that adds new customers 
 to the database. It leaves the saved flag false to 
 indicate that the data is not stored in the database 
 yet. 
 */ 
 public Customer(int id, String name, Address address) { 
 this.id = id; 
 this.name = name; 
 this.address = address; 
 } 
 
 Constructs a Customer object. This constructor is 
 called only by CustomerList as it populates its 
 contents. 
 */ 
 public Customer(int id, 
 String lastName, 
 String firstName, 
 String address, 
 String city, 
 String state, 
 String country, 
 String zip) { 
 
 initialize(id, lastName, firstName, address, 
 city, state, country, zip); 
 } 
 
 /** 
 Initializes the contents of this object based on 
 physical data. This is the mapping of data from 
 its relational form to its domain object form. 
 */ 
 private void initialize(int id, 
 String lastName, 
 String firstName, 
 String address, 
 String city, 
 String state, 
 String country, 
 String zip) { 
 
 // Combine the first and last names, since 
 // that is how the application 
 // needs them. 
 StringBuffer buffer = new StringBuffer();
buffer.append(lastName); 
 buffer.append(", "); 
 buffer.append(firstName); 
 name = buffer.toString(); 
 
 // Combine the city and state, since 
 // that is how the application 
 // needs them. 
 buffer = new StringBuffer(); 
 buffer.append(city); 
 buffer.append(", "); 
 buffer.append(state); 
 String cityState = buffer.toString(); 
 
 // Initialize the address. 
 this.address = new Address(); 
 this.address.setAddress1(address); 
 this.address.setCityState(cityState); 
 this.address.setCountry(country); 
 this.address.setPostalCode(zip); 
 
 // Set this to true, since this information 
 // was read from the database. 
 saved = true; 
 } 
 
 public String getName() { 
 return name; 
 } 
 
 public void setName(String name) { 
 this.name = name; 
 } 
 
 public Address getAddress() { 
 return address; 
 } 
 
 public void setAddress(Address address) { 
 this.address = address; 
 } 
 
 /** 
 Saves the customer information to the database. 
 This is the mapping of data from its domain object 
 form to its relational form. It uses the saved flag 
 to determine whether to insert new data or update 
 existing data. 
 */ 
 public void save() throws DataException 
 { 
 // Split the name into first and last, since 
 // the CUSTOMERS table stores these items in separate 
 // columns. 
 String first; 
 String last; 
 int comma = name.indexOf(','); 
 if (comma >= 0) { 
 first = name.substring(comma + 1).trim(); 
 last = name.substring(0, comma).trim(); 
 } 
 else { 
 first = ""; 
 last = name; 
 } 
 
 // Split the city and state, since the CUSTOMERS table 
 // stores these items in separate columns. 
 String cityState = address.getCityState(); 
 String city = ""; 
 String state = ""; 
 if (cityState != null) { 
 comma = cityState.indexOf(','); 
 if (comma >= 0) { 
 city = cityState.substring(0, comma).trim(); 
 state = cityState.substring(comma).trim(); 
 } 
 else { 
 city = cityState; 
 } 
 } 
 
 try { 
 Connection connection 
 = ConnectionFactory.getConnection(); 
 
 // If the customer information came from 
 // the database, then issue an update. 
 if (saved) { 
 PreparedStatement statement 
 = connection.prepareStatement(UPDATE); 
 statement.setString(1, last); 
 statement.setString(2, first); 
 statement.setString(3, address.getAddress1()); 
 statement.setString(4, city); 
 statement.setString(5, state); 
 statement.setString(6, address.getCountry()); 
 statement.setString(7, address.getPostalCode()); 
 statement.setInt(8, id); 
 statement.executeUpdate(); 
 statement.close(); 
 } 
 
 // If the customer information did not 
 // come from the database, then issue an insert. 
 else { 
 PreparedStatement statement 
 = connection.prepareStatement(INSERT); 
 statement.setString(1, last); 
 statement.setString(2, first); 
 statement.setString(3, address.getAddress1()); 
 statement.setString(4, city); 
 statement.setString(5, state); 
 statement.setString(6, address.getCountry()); 
 statement.setString(7, address.getPostalCode()); 
 statement.setInt(8, id); 
 statement.executeUpdate(); 
 statement.close(); 
 
 // Indicate that the information now exists 
 // in the database. 
 saved = true; 
 } 
 
 connection.close(); 
 } 
 catch(SQLException e) { 
 throw new DataException("Unable to save customer " 
 + id, e); 
 } 
 } 
} 
 
 
 
 
Caso de Uso : Georeferenciar 
Detalle de la extensión de las entidades Tienda, Almacén y Cliente para añadirle 
características de Georeferenciacion. 
 
En el diagrama anterior GeoEntidad es una clase base con un contructor por defecto. Las 
propiedades x,y serán asignadas posteriormente en el caso de uso Georeferenciar 
Nota :El alumno deberá cambiar el constructor de cada subclase 
 class GeoEntidad
Class Model::
Cliente
Class Model::
Tienda
Class Model::
Almacen
GeoEntidad
- x: int
- y: int
+ GeoEntidad() : void
+ getX() : int
+ getY() : int
+ setX(int) : void
+ setY(int) : void
 
Caso de Uso : Georeferenciar 
Detalle del diagrama de actividades para la clase ControladorServicioCUGeoreferenciar 
 
 
Para la actividad de Georeferenciación el alumno dispondrá de la librería GeoRefrenciación Lib 
 
Caso de Uso : Georeferenciar 
Este caso de uso contempla la asignación de un par de coordenadas a cada entidad con 
propiedades de localización espacial ( ver jerarquía anterior) 
Detalle de diagrama de clases 
 
 act Dynamic View
Obtener Entidades
Georefrenciar Entidades
Grabar estado de 
georeferenciación de 
Entidades
Incio
ControladorServicioCUGeoReferenciar
fin
 
Donde 
geoReferenciar(String cod_postal,String dirección,String poblacion):int[] 
es el método de la interfaz IGeoRefrenciador que permite obtener la coordenadas geográficas 
de una Entidad dadas sus características de ubicación (cod_postal,dirección y población) 
Este caso de uso considera el patrón Simple Factory visto en clase, para desacoplar el 
controlador de Servicio respecto del componente de Georeferenciación 
 
 class CUGeoreferenciar
ControladorServ icioCUGeoReferenciar
+ desarrollarServicio() : bool
«interface»
IGeoReferenciador
+ geoReferenciar(String, String, String) : int[]
GeoReferenciadorFactory
+ crear() : IGeoReferenciador
GeoReferenciador
- mapCodPostal: HashMap
+ GeoReferenciador() : void
+ geoReferenciar(String, String, String) : int []
- obtenerCoordenadas(Rectangle) : void
Class Model::
ContenedorAlmacenesSingleton
+ borrarElementos() : void
+ grabarElementos() : void
Class Model::
ContenedorClientesSingleton
+ borrarElementos() : void
+ grabarElementos() : void
Class Model::
ContenedorTiendasSingleton
+ borrarElementos() : void
+ grabarElementos() : void
1
1
1
«uso»
crea
implementa
Aplicaciones 2015-2016 Campus/DOCUMENTO DE TRABAJO N2 fecha 3_4_2013.pdf
Asignatura PROGRAMACIÓN DE APLICACIÓN 
A continuación se muestras consideraciones de diseño de los siguientes casos de uso 
 Caso de Uso : Eliminar Datos de Carga del Sistema 
 Caso de Uso : Ver Informe de Carga 
 Caso de Uso :Grabar Datos de Carga 
 
Caso de Uso : Eliminar Datos de Carga del Sistema 
Diagrama de clases de diseño 
Nota : Este caso de uso contempla el borrado de los datos almacenados en los contenedores y 
en la base de datos si se hubieran grabado 
 
Diagrama de comunicación 
 
 
Caso de Uso : Ver Informe de Carga 
Diagrama de clases 
Nota :En este diagrama no se muestra la parte de la interfaz 
 
Noata: La clase AuditoriaCarga es una agregado de objetos Registro de carga 
La clase ArchivoResultado leerá del archivo de texto los registros correspondientes
Diagrama de secuencia 
 
 
 
Caso de Uso :Grabar Datos de Carga 
Diagrama de clases de diseño 
 
 
Diagrama de secuencia 
Nota : Este diagrama es parcial, ya que sólo se muestra la interacción con uno de los 
contenedores. El alumno debe derivar el resto de la interacción con los otros contenedores. 
Otra consideración importante es el orden de grabación de datos en la base de datos. Este 
orden deberá respetar las restricciones de integridad referencial 
 
Aplicaciones 2015-2016 Campus/Anexo I Interfaces java.pdf
1 
 
Programación de Aplicaciones. Introducción al 
diseño basado en componentes 
Anexo I Interfaces Java 
1. Definición de una interfaz en Java 
La definición de una interfaz en Java se realiza de la siguiente forma: 
[public ] interface nombre_interfaz { 
<cuerpo de la interfaz> 
} 
Donde <cuerpo de la interfaz> es igual al conjunto de métodos abstractos que define la 
interfaz. <cuerpo de interfaz> puede ser solamente declaraciones de métodos sin cuerpo y 
constantes . 
El modificador public indica que la interfaz puede ser utilizada por cualquier clase de cualquier 
otro paquete. Si no se indica public la interfaz sólo estará disponible para las clases del mismo 
paquete 
Ejemplo de declaración de una interfaz denominada IActivación con un único método 
abstracto 
public interface IActivacion{ 
void activar(); 
} 
Una interfaz puede heredar o extender otra interfaz. Para ello se usa la siguiente sintaxis: 
[public ] interface nombre_interfaz extends nombre_interfaz_base { 
<cuerpo de la interfaz> 
} 
Nota importante: El nombre de la interfaz se puede usar en cualquier lugar donde se pueda 
usar el nombre de una clase. 
Las interfaces al igual que las clases y métodos abstractos proporcionan plantillas de 
comportamiento que se espera que sea implementada por otras clases. Una interfaz 
recordemos no implementa métodos, sólo los define (también puede definir constantes). 
Por ejemplo para este diagrama de clases la interfaz Activar proporciona un forma de activar y 
desactivar cualquier dispositivo 
2 
 
<<interface>>
Activar
activar()
desactivar()
activar()
desactivar()
Zona
activar()
desactivar()
Sensor
activar()
desactivar()
activar()
desactivar()
SensorZona
Activar
Operaciones 
polimórficas
a) Notación basada en clases
Interface
Realización
a) Notación simplificada
1
*
 
 
2. Implementar una interfaz Java 
Para que una clase implemente una interfaz definida, hay que usar la palabra reservada 
implements como se muestra a continuación: 
[public ] class nombre_clase implements nombre_interfaz { 
<cuerpo de la clase> 
} 
Nota : La palabra reservada implements sigue a extends si esta existiera 
En el ejemplo anterior 
class Zona implements Activar{ 
public Zona(){//constructor} 
void activar() { 
//Implementación 
} 
void desactivar(){ 
//Implementación 
} 
 } 
class Sensor implements Activar{ 
public Sensor(){//constructor} 
void activar() { 
//Implementación 
} 
3 
 
void desactivar(){ 
//Implementación 
} 
} 
Una clase puede implementar varias interfaces 
Ejemplo 
 
class Identificacion implements OperacionesVerificaciónFirma, 
OperacionesCifrado 
Como una interfaz sólo aporta declaraciones de métodos abstractos es obligado 
implementarlos. No podemos elegir y definir sólo aquellos métodos que necesitemos, en el 
momento de definir la clase de esta forma, se obligará a que la clase implemente todos y cada 
uno de los métodos definidos por la interfaz, si no es así el programa no compilará. 
Si una clase implementa una interfaz y posteriormente se crean subclases, las subclases 
heredarán todos los nuevos métodos que haya implementado la clase base. 
El tipo de un objeto nunca es un interfaz. Sin embargo una variable puede ser de tipo 
interfaz. La variable contendrá una referencia a un objeto que implementa la interfaz 
3. Clases abstractas e interfaces 
¿Sería equivalente un diseño con una clase abstracta?. La respuesta es no. Si se define una 
clase abstracta una subclase podría heredar métodos públicos de la clase base, asociaciones y 
atributos. Sin embargo una clase que implementa una interfaz debe sobrescribir métodos 
abstractos y no hereda nada (métodos públicos, relaciones etc). Hay que recordar que una 
interfaz no define asociaciones. 
Aunque ambos conceptos tienen algo en común y es que permiten definir una especie de 
contrato. Una clase abstracta impone la restricción de que toda subclase debe implementar las 
operaciones abstractas, en este sentido si son iguales. Por otro lado una clase abstracta forma 
un concepto general que da sentido a una relación jerárquica. Sine embargo una interfaz no 
tiene esa finalidad 
4. Utilizar una interfaz como un tipo de dato 
Una interfaz es un nuevo tipo de dato, por lo tanto el nombre de una interfaz puede aparecer 
en cualquier sitio donde aparezca un tipo de datos. 
public class Controlador{ 
IActivacion dispositivos[]; 
public void registrarDispositivo (IActivacion disp){…} 
4 
 
} 
Una variable de tipo interfaz espera referenciar a un objeto que tenga implementada dicha 
interfaz, de lo contrario el compilador de java mostrará un error. 
Así mismo se puede convertir implícitamente referencias a objetos que implementan una 
interfaz en referencias a esa interfaz y viceversa, pero en este caso la conversión debe ser 
explicita. 
El siguiente ejemplo muestra tres clases no relacionadas que por el hecho de implementar una 
interfaz pueden formar parte de la misma colección y aplicar la definición del polimorfismo 
para tratarlas de forma homogenea 
 
+activar()
«interface»
IActivacion
+activar()
Sensor
+activar()
Alarma
+activar()
MonitorControl
 
//… 
IActivacion dispositivos[]; 
dipositivos[0]= new Sensor(); 
dispositivos[1]= new Alarma(); 
dispositivos[2]= new MonitorControl(); 
dispositivos[0].activar(); 
//… 
 
5. Interfaces y herencia múltiple 
A menudo se piensa en los interfaces como una alternativa a la herencia múltiple. Pero la 
realidad es que ambos conceptos, herencia e interfaces son bastantes diferentes, más 
concretamente las diferencias son: 
 Desde la interfaz una clase sólo puede heredar constantes 
 Desde la interfaz una clase no puede heredar métodos definidos 
 La jerarquía de interfaces es independiente a la jerarquía de clases. De hecho varias 
clases pueden implementar la misma interfaz y no pertenecer a la misma jerarquía de 
5 
 
clases. En cambio cuando se hable de herencia múltiple todas las clases pertenecen a 
la misma jerarquía. 
C++ si permite herencia múltiple pero Java y C# no la permiten aunque en la práctica no llega a 
ser un problema real. 
6. Para que sirve una interfaz 
Una interfaz se utiliza para definir un comportamiento abstracto, un pseudocontrato entre 
una clase que va a usar la interfaz y una clase que deberá dar una implementación a cada uno 
de los métodos definidos en la interfaz. Resumimos a continuación algunas de las situaciones 
donde las interfaces pueden ser útiles. 
 Captar comportamiento similar entre clases no relacionadas sin forzar entre ellas una 
relación artificial. Una acción de este tipo permite tratar a este conjunto de clase como 
un conjunto de objetos homogéneo, usando el polimorfismo. 
 Declarar un conjunto de operaciones que varias clases deben implementar en 
determinadas situaciones ( Por ejemplo en Java toda clase que debe ejecutarse como 
un hilo concurrente debe implementar la interfaz Runnable) 
 Desacoplar un clase cliente de la clase que implementa la interfaz 
 Permite definir un contrato sin preocuparnos por los detalles de la implementación 
 
 
Aplicaciones 2015-2016 Campus/Tema patrones software 2013.pdf
INTRODUCCIÓN
PATRONES SOFTWARE 
 
Gustavo Millán García 
ORÍGENES 
 The Timeless Way of Building [Alexander79], 
 
“Cada patrón es una regla de 3 partes, que expresa una relación entre un contexto, un problema y 
una solución. Como un elemento en el mundo, cada patrón es una relación entre un contexto, un 
sistema de fuerzas que ocurren repetidamente en ese contexto y una configuración espacial que 
permite que esas fuerzas se resuelvan entre sí.” 
En 1977, en el libro A Pattern Language, Alexander presenta junto a otros colegas estas 
teorías y el uso de la metáfora de patrón, que define de la siguiente manera: 
“Cada patrón describe un problema que ocurre una y otra vez en nuestro entorno, para describir 
después el núcleo de la solución a ese problema, de tal manera que esa solución pueda ser usada 
más de un millón de veces sin hacerlo ni siquiera dos veces de la misma forma.” 
HISTORIA. CONCEPTO PATRÓN EN EL 
ÁMBITO DEL DESARROLLO DE SOFTWARE 
 Eric Gamma, Richard Helm, Ralph Johnson y John Vlissides publicaron el 
primer catálogo de patrones en el ámbito del software 
 Design Patterns: Elements of Reusable Object-Oriented Software. Reading, MA: Addison-
Wesley, ©1995. 
 Se inspiraron en el trabajo de Christopher Alexander, que había documentado 
patrones en el ámbito de la arquitectura civil 
 Pattern-Oriented Software Architecture: A System of Patterns (POSA) 
 Primer libro en hacer una clasificación de patrones 
 Patrones arquitectónicos 
 Patrones de diseño 
 Patrones elementales (Idioms) 
DEFINICIÓN DEL TÉRMINO PATRÓN 
SOFTWARE 
 Es una solución a un problema recurrente que surge en un 
contexto determinado [POSA] 
 Documenta diseños probados y basado en la experiencia 
 Especifica una configuración de elementos y su comportamiento 
 El contexto de un patron describe cuando puede surgir el problema 
 
SOBRE EL USO DE PATRONES Y LA 
INGENIERÍA SOFTWARE 
 A medida que ha aumentado el uso de los patrones se ha tenido certeza de que 
éstos pueden mejorar la productividad y calidad de las soluciones software gracias a 
las siguientes cualidades (Chambers et al., 2000): 
 Promueven la reutilización de diseño. Los patrones de diseño capturan 
experiencias en la resolución de problemas de diseño cuya utilidad o necesidad se ha 
evidenciado repetidamente en diferentes proyectos. Por lo tanto, la aplicación de un 
patrón lleva implícita la reutilización de esos diseños. 
 Forman un vocabulario común de diseño. Los nombres de los patrones 
pueden ayudar a los diseñadores a comunicarse de una manera más eficiente, 
extendiendo su vocabulario y siendo capaces de transmitir el problema y la solución 
como un todo comprensible mediante el nombre del patrón. 
 Mejoran la documentación. La utilización de un patrón en el desarrollo de un 
sistema permite conocer qué solución se ha aplicado y por qué, puesto que el 
patrón no es una idea del programador sino una solución probada y reconocida en 
una comunidad de desarrollo. 
 
CONSIDERACIONES GENERALES SOBRE EL 
USO DE PATRONES(I) 
 Encontrar el patrón adecuado no es fácil. 
 La implementación de forma correcta de patrones requiere 
experiencia. 
 El uso de patrones no da automáticamente como resultado un 
diseño de alta calidad. 
 Normalmente la gente ve los patrones como plantillas o como bloques 
modulares de construcción. No son plantillas! 
 Los patrones no automatizan el proceso de desarrollo del 
software. 
 
CONSIDERACIONES GENERALES SOBRE EL 
USO DE PATRONES(II) 
 Los Patrones software no son una solución completa en si misma 
 Los Patrones complementan , pero no sustituyen otras técnicas y 
métodos dentro de la ingeniería de software. 
 Los patrones no son un sustituto de la inteligencia ý creatividad del 
ingeniero software. 
 No hay que forzar la aplicación de patrones, hay que usarlos con 
cuidado 
TIPOS DE PATRONES SOFTWARE 
 Patrones de Arquitectura 
 Los patrones de arquitectura expresan el esquema fundamental de organización de sistemas 
software. Proveen un conjunto de subsistemas predefinidos, especifican sus responsabilidades e 
incluyen reglas y guías para organizar las relaciones entre ellos. [POSA96] 
 Patrones de Diseño 
 Un patrón de diseño describe una estructura recurrente de componentes que se comunican para 
resolver un problema general de diseño en un contexto particular [GoF95]. 
 Tipos : De creación , estructurales y de comportamiento 
 Idioms 
 Es un patrón considerado especificamente en un lenguaje de programación. Describe como 
implementar aspectos de componentes y sus relaciones en un lenguaje de programación 
 
 La diferencia entre estas clases de patrones esta en su nivel de abstracción y su 
nivel de detalle ( los patrones de aquitectura son mucho más abstractos que 
idioms) 
DESCRIPCIÓN DE UN PATRÓN SOFTWARE 
 Nombre: Un nombre descriptivo y único que ayude a identificar y referenciar al patrón. 
 Problema: Descripción resumida en una o dos frases que describe la intención del patrón, es decir, las metas y objetivos que se quieren 
alcanzar. 
 Contexto: Problema recurrente en el que es aplicable el patrón. 
 Fuerzas: Descripción de las fuerzas, los objetivos y restricciones relevantes para ese patrón, y de cómo éstas interaccionan entre ellas o 
con las metas que deseamos alcanzar. Además se puede incluir un escenario concreto que sirva de motivación para el patrón. La noción 
de fuerza generaliza los tipos de criterios que justifican al patrón. 
 Solución: Suele ser un conjunto de instrucciones que describen cómo construir el producto resultante. La descripción puede ir 
acompañada de dibujos, diagramas o esquemas de la solución. Es el corazón del patrón. El patrón North Face nos indica las siguientes 
instrucciones: “Haz de la cara norte del edificio una cascada que descienda hacia el suelo para que el sol que normalmente proyecta una 
larga sombra hacia el norte alcance el suelo inmediatamente al lado del edificio”. 
 Ejemplos: Ejemplos, que pueden ser visuales, que ayudan al lector a entender el uso y la aplicabilidad del patrón (el contexto inicial, 
cómo el patrón transforma el contexto, y el contexto resultante). En el patrón North Face se presenta un ejemplo visual de la aplicación 
del patrón sobre el contexto inicial, como se puede ver en la parte derecha de la figura 2.2.b. 
 Contexto resultante: Indica el estado del sistema después de aplicar el patrón, incluyendo sus consecuencias (positivas y negativas). 
 Exposición razonada: Expone cómo funciona el patrón y por qué es útil. Mientras que la solución muestra la estructura visible del 
patrón, la exposición explica sus mecanismos subyacentes. 
 Patrones relacionados: Patrones que se pueden combinar con este, o es posible aplicar a partir del contexto resultante. 
 
¿COMO SE DECIDE QUE ES UN PATRÓN? 
 ¿Como se decide que es lo que hace que algo sea un buen patrón?: Las 
conferencias PoLP ( Pattern Language of Programs) han establecido varios 
críterios para aceptar publicaciones o consideraciones de nuevos patrones. 
Estos criterios estan resumidos en Buschmann et. al. in Pattern-Oriented 
Software Architecture 
 Enfoque práctico: Los patrones deben describir soluciones probadas para problemas 
recurrentes más que el último avance cientifico 
 No busqueda de originalidad: Las personas que descubren patrones no necesitan ser 
inventores o descubridores 
 Revisión pública: 
 Talleres en lugar de presentaciones: Más que ser presentados por su autor los 
patrones son discutidos en talleres, que son foros abiertos donde se busca la mejora 
continua. 
 Minuciosamente publicados 
 
http://hillside.net/patterns/books/
http://hillside.net/patterns/books/
http://hillside.net/patterns/books/
http://hillside.net/patterns/books/
CARACTERISTICAS 
 Un buen
patrón debe tener las siguientes características (Coplien, 1998): 
 Resolver un problema: Los patrones capturan soluciones, no sólo principios 
abstractos o estrategias. 
 Ser un concepto probado: Los patrones capturan soluciones con un registro de los 
pasos a llevar a cabo, no teorías o especulaciones. 
 La solución propuesta no es obvia: Muchas técnicas de resolución de problemas 
intentan derivar la solución a partir de principios. Los mejores patrones generan una 
solución a un problema de manera indirecta, una aproximación necesaria para los 
problemas más difíciles de diseño. 
 Describir una relación: Los patrones no sólo describen módulos, sino estructuras y 
mecanismos del sistema en detalle. 
 Tener un componente humano significativo, minimizando así su intervención: El 
software sirve a la comodidad humana o a la calidad de vida; los mejores patrones 
explícitamente apelan a la estética y a la utilidad. 
 
PATRONES DE ARQUITECTURA 
 Definen un estructura global de organización del sistema software 
 MVC (Model- View-Controller) 
 Layers 
 Pipes and Filtres 
 Blackboard 
 Broker 
 Presentation-Abstraction-Control 
 Microkernel 
 Reflection 
 
PATRONES DE DISEÑO 
 Patrones de diseño [GoF 95] 
EJEMPLO DE PATRÓN ARQUITECTURA 
 ¿Cómo se puede dividir la funcionalidad del sistema 
?de forma que: 
 La funcionalidad de un nivel de abstracción este tan 
desacoplada como sea posible del resto 
 La funcionalidad de un determinado nivel de 
abstracción evolucione de forma independiente a las 
demás sin afectarlas 
 Solución 
 Definir una o más capas , donde cada capa tenga un única 
responsabilidad clara y bien definida de acuerdo a su nivel 
de abstracción Y grado de variación 
 Patrón Layers 
PATRÓN DE ARQUITECTURA MVC 
 Problema 
 Como se puede desarrollar sistemás interactivos con 
interfaces gráficas de usuario de forma que: 
 Soporten adaptaciones y cambios sin afectar a la funcionalidad 
nucleo del sistema 
 La interfaz gráfica muestre el estado del proceso y que también se 
actualize ante cambios de estado interno 
 Solución 
 Dividir la aplicación interactiva en tres componentes 
debilmente acoplados 
 Componente Model : Encapsula la funcionalidad nucleo de la 
aplicación y es independiente de su representación 
 Componente View: Encargado de presentar la información de 
forma gráfica al usuario 
 Componente Controller: Están asociados con las vistas y el 
modelo. Permiten manipular el modelo y seleccionar la vista a 
adecuada 
EJEMPLO DE PATRONES DE DISEÑO 
 
 Patrón Active Domain Object (Data Access patterns addison Wedsley 2003) 
 Contexto 
 Aplicaciones que manipulan directamente filas de tablas relacionales 
 Aplicabilidad 
 Se desea ocultar el modelo de datos físico y la complejidad del acceso a estos datos 
 Se desea encapsular toda la lógica de acceso en un único componente conceptual 
 Se dese enmascarar las posibles inconsistencia en en modelo de datos fisico 
 Solución 
 El patrón Active Domain object aborda esta cuestión encapculando el modelo de datos 
dentro de un conjunto de objetos de dominio 
 Estructura del patrón 
EJEMPLO DE PATRONES DE DISEÑO (II) 
 Comportamiento 
EJEMPLO DE PATRONES DE DISEÑO (III) 
 Beneficios 
 Proporciona un codigo de aplicación más limpio y facil de mantener 
 Desacopla el código de aplicación del modelo fisico relacional de datos 
 Inconvenientes 
 Esparce el código de acceso a datos en múltiple objetos de dominio. Cada active 
domain object es responsible de su propieo implementación de acceso a datos en la 
base de datos relacional 
 No es una estructura adecuada para politicas generales de acceso a datos (ej cache, 
pool de conexiones,etc) 
 Limita el control de acceso a datos. 
 
PATRÓN DE DISEÑO SINGLETON (I) 
 Propósito: 
 Asegurar que una clase sólo tiene un ejemplar, y 
 proporcionar un punto de acceso global a éste 
 Motivación 
 Algunas clases sólo necesitan exactamente un ejemplar 
 Un spooler de impresión en un sistema, aunque haya varias impresoras 
 Un sólo sistema de archivos 
 Un sólo gestor de ventanas 
 ... 
 En vez de tener una variable global para acceder a ese ejemplar único, la clase se 
encarga de proporcionar unmétodo de acceso 
PATRÓN DE DISEÑO SINGLETON (II) 
 Aplicación 
 Cuando sólo puede haber un ejemplar de una clase, y debe ser accesible a los 
clientes desde un punto de acceso bien conocido 
 Cuando el único ejemplar pudiera ser extensible por herencia, y los clientes deberían 
usar el ejemplar de una subclase sin modificar su código 
 Esquema, participantes y colaboraciones 
 Los clientes acceden al ejemplar de Singleton únicamente através del método 
Instance de la clase Singleton 
PATRÓN DE DISEÑO SINGLETON (III) 
 Consecuencias 
 Acceso controlado a un ejemplar único 
 Espacio de nombres reducido 
 Evita la necesidad de utilizar variables globales 
 Se puede heredar de la clase Singleton para configurar el ejemplar para una 
aplicación concreta 
 Permite un número de ejemplares variable 
 Es posible tener un conjunto de ejemplares en vez de uno sólo: 
 Object Pool 
 Más flexible que las operaciones de clase (static) 
 Con static no es posible considerar que hubiera más de un solo ejemplar 
 En C++ las funciones static no pueden ser virtuales, y por tanto las subclases no 
pueden redefinirlas polimórficamente 
PATRÓN DE DISEÑO SINGLETON (IV) 
 Implementación 
 
class Singleton { 
private static Singleton instancia = null; 
public static Singleton getInstancia() { 
 if ( instancia == null ) 
 instancia = new Singleton(); 
 return instancia 
} 
protected Singleton() { 
 // creación de la instancia 
} 
public void metodo() {...} 
} 
PATRÓN DE DISEÑO SINGLETON (IV) 
 Aplicabilidad 
 Deba haber exactamente una instancia de una clase y ésta deba ser accesible a los clientes 
desde un punto de acceso conocido. 
 La única instancia debería ser extensible mediante herencia y los clientes deberían ser 
capaces de utilizar una instancia extendida sin modificar su código. 
 Consecuencias 
 Acceso controlado a la única instancia. Puede tener un control estricto sobre cómo y 
cuando acceden los clientes a la instancia. 
 Espacio de nombres reducido. El patrón Singleton es una mejora sobre las variables 
globales. 
 Permite el refinamiento de operaciones y la representación. Se puede crear una subclase 
de Singleton. 
 Permite un número variable de instancias. El patrón hace que sea fácil cambiar de opinión y 
permitir más de una instancia de la clase Singleton. 
 Más flexible que las operaciones de clase (static en C#, Shared en VB .NET). 
EJEMPLOS PATRONES IDIOMS 
 http://c2.com/ppr/wiki/JavaIdioms/JavaIdioms.html 
COMUNIDAD DE INVESTIGACIÓN Y 
ESTUDIO DE PATRONES 
 Comunidad de trabajo sobre patrones 
 http://hillside.net/patterns/ 
 Pattern Conferences 
 – PLoP®since 1994 at AllertonHouse, Monticello, IL* 
 
http://hillside.net/patterns/
Aplicaciones 2015-2016 Campus/diagramas UML v2.pdf
Este documento muestra la equivalencia en UML de los diagramas usados en el libro. 
CAPITULO 1 
 
 
 
Ventana de Aplicacion
Contedor
Boton Etiqueta Campo de texto
 
Figura 1.5 Jerarquía de componentes 
 
 
:Conversor :JPanel
:JButton
:JLabel
:JLabel
:JTextField
:JFrame
<<Interface>>
ActionListener
1
1
1
1
 
 
CAPITULO 2 
 
 
Ventana:VentanaTraductor panelContenido:JPanel
boton:JButton
etiqueta:JLabel
campo:JTextField
:Traductor
<<Interface>>
ActionListenerJFrame
:AplicaciónTraductor
1
1
1
1
 
 
 
Ventana:VentanaTraductor :PanelTraductor
Boton:JButton
Etiqueta:JLabel
campo:JTextField
:Traductor
<<Interface>>
ActionListenerJFrame
:AplicaciónTraductor
JPanel
1
1
1
 
 
 
 
Ventana:VentanaTraductor :PanelTraductor
Boton:JButton
Etiqueta:JLabel
campo:JTextField
:Traductor
<<Interface>>
ActionListenerJFrame
:AplicaciónTraductor
JPanel
1
1
1
1
 
 
 
 
 
Ventana:VentanaTraductor :PanelTraductor
boton:JButton
etiqueta:JLabel
campo:JTextField
:Traductor
<<Interface>>
ActionListenerJFrame
:AplicaciónTraductor
JPanel
etiqCambioIdioma:JLabel
botonCambioIdioma:Jbutton
1
1
1
1
1
1
 
Ventana:VentanaTraductor :PanelTraductor
Boton:JButton
Etiqueta:JLabel
campo:JTextField
:Traductor
<<Interface>>
ActionListenerJFrame
:AplicaciónTraductor
JPanel
etiqCambioIdioma:JLabel
botonCambioIdioma:Jbutton
:GestorEventosRollOver
<<Interface>>
MouseListener
1
1
1
1
1
1
 
 
 
 
 
Aplicaciones 2015-2016 Campus/geolib.jar
META-INF/MANIFEST.MF
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.8.3
Created-By: 1.6.0_26-b03 (Sun Microsystems Inc.)
org/geo/GeoReferenciador.class
package org.geo;
public synchronized class GeoReferenciador implements IGeoReferenciador {
 private java.util.HashMap mapCodPostal;
 public void GeoReferenciador();
 public int[] georeferenciar(String, String, String);
 private int[] obtenerCoordenadas(java.awt.Rectangle);
 public static void main(String[]);
}
org/geo/GeoReferenciadorFactory.class
package org.geo;
public synchronized class GeoReferenciadorFactory {
 public void GeoReferenciadorFactory();
 public static IGeoReferenciador crear();
}
org/geo/IGeoReferenciador.class
package org.geo;
public abstract interface IGeoReferenciador {
 public abstract int[] georeferenciar(String, String, String);
}
Aplicaciones 2015-2016 Campus/BLOQUE I EJERCICICOS SOBRE INTERFACES.pdf
 
 
1 
 
Programación de aplicaciones. Diseño basado en 
componentes 
Ejercicios 
Requisitos previos 
 Tema 1.Diseño basado en componentes 
 Anexo I. Definición de interfaces Java 
 Conocimientos de programación orientada a objetos 
Objetivos de la práctica 
 Conocer cómo tratar abstracciones 
 Introducir al alumno en el diseño de colaboraciones entre clases usando interfaces 
 
 
Índice 
 
EJERCICIO PRÁCTICO 1 .................................................................................................................. 2 
EJERCICIO PRÁCTICO 2 ................................................................................................................. 3 
 
 
 
 
 
 
 
2 
 
 
EJERCICIO PRÁCTICO 1 
Dado un sistema Domótico, donde existe una clase denominada ControladorInstalación que 
controla los distintos dispositivos de la instalación (sensores, alarmas, actuadores, etc). 
 
SensorTemperaturaSensorPresencia Alarma
Actuador
Id: int
Unidad: String
Estado:String
Lectura:double
Id:int
Tipo :String
Estado:String
1
1
Id: int
Unidad: String
Estado:String
Lectura:double
ControladorInstalacion
activarDispositivos()
desactivarDispositivos()
Id:int
Estado:String
 
Se pide : 
a) Realice un diseño basado en el uso de interfaces de forma que la clase 
ControladorInstalacion pueda activar o desactivar a cualquier tipo de dispositivo de la 
instalación existente y que en un futuro se pueda incorporar a la instalación 
b) Realice el diagrama UML estructural del diseño anterior 
Cuestiones: 
1.-Donde se encuentra el punto de variabilidad en este diseño 
2.-¿Qué efectos provocaría en el diseño del ControladorInstalacion la introducción de un 
nuevo tipo de dispositivo? 
3.- ¿ Se está haciendo uso en esta práctica del polimorfismo?. Explique de qué forma y donde 
4.- Realice un diagrama del comportamiento del sistema cuando el operador da la orden al 
sistema de activar dispositivo. 
 
 
 
3 
 
 
EJERCICIO PRÁCTICO 2 
Se desea proporcionar una manera de integrar un Sistema central (GestorVentas) con una 
serie de sistemas externos. Los sistema externos son: un sistema CRM (Custom Relationship 
Customer) que se encarga de la gestión de la información de todos los clientes de la compañía, 
otro es un sistema de registros de proveedores y el último es un sistema de gestión de 
almacén. La siguiente figura muestra las abstracciones realizadas. Se debe tener en cuenta que 
los sistemas anteriores no pueden ser modificados. 
GestorVentas
AdaptadorCRM
AdaptadorSistemaAlmacen
AdaptadorSistemaProveedor
 
Para todos ellos existe una lógica común que usa el sistema GestorVentas y que consiste en las 
siguientes operaciones 
 Como todos son sistemas independientes para cada uno se debe desarrollar la 
operación conectar() 
 Para todos ellos existe la operación obtenerInfo (String consulta) donde consulta es 
una expresión que indica la información a obtener de sistema remoto 
 Para todos se debe poder ejecutar la operación cerrar() 
Se pide 
Dadas las clases denominadas GestorVentas, AdaptadorCRM, AdaptadorSistemaAlmacen y 
AdaptadorSistemaProvedor 
a) Proporcione solución de diseño de forma que el sistema GestorVentas integre los 
sistemas externos 
b) Realice un diagrama UML del diseño obtenido 
c) Estudie el acoplamiento entre el sistema y los sistemas internos. 
 
Aplicaciones 2015-2016 Campus/anexo Java 2D v3.pdf
Facultad de Informática 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería de Software 
Universidad Pontificia de Salamanca en Madrid 
Universidad Pontificia de Salamanca 
en Madrid 
Universidad Pontificia de Salamanca en Madrid 
Programación de Aplicaciones 
 
 
 
Introducción a la programación gráfica 
con Java2D 
 
Gustavo Millán García 
 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –2– 
Introducción Java2D 
 Permite la creación gráficos avanzados o de efectos 
relacionados con imágenes 
 Puede ser usada para el desarrollo de animaciones u otras 
presentaciones multimedia al combinarla con otras APIs 
de Java, como puedan ser JMF (Java Media framework - 
Entorno de Trabajo de Java para Médios Audiovisuales) o 
Java 3D. 
 La API Java2D amplía muchas de las capacidades gráficas 
de la biblioteca AWT (Abstract Window Toolkit ) 
 renderizado, figuras geométricas, uso de fuentes de letras, 
manipulación de imágenes y el enriquecimiento en la definición del 
color. 
 Demo \jdk1.2\demo\jfc\Java2D 
 
 
 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –3– 
Clase Graphics2D 
 Clase java.awt.Graphics2D (abstract) 
 Es una clase que extiende a java.awt.Graphics proporcionando un control 
más potente sobre la presentación de texto, imágenes o figuras geométricas. 
 Un objeto Graphics ( es una clase abstracta) , 
representa un área de dibujo y el contexto en el que 
puede dibujarse algo. Ejemplo 
public void paint (Graphics g) { 
Rectangle2D r2 = new Rectangle2D.Float(75, 50, 100, 25); 
Graphics2D g2 = (Graphics2D)g; 
g2.draw(r2); 
} 
 Esta área de dibujo puede vincularse con distintos 
medios como un monitor, o una imagen en memoria 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –4– 
Objeto Graphics2D 
 Los métodos de Graphics2D se pueden dividir en dos 
grupos 
 Métodos para dibujar y pintar formas geométricas, texto e 
imágenes 
 
 
 
 
 
 Métodos para establecer artributos que afectan al dibujo y 
representación gráfica de objetos. 
 
 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –5– 
Objeto Graphics2D 
Métodos para dibujar 
 drawText Pintar texto 
g.drawString(“Prueba", 10, 10); 
 drawImagePintar una imagen 
g.drawImage(img, 0, 0, width, height, 0, 
0, imageWidth, imageHeight, null); 
 drawLine, drawArc, drawRect, drawOval, drawPolygon 
Para dibujar figuras geométricas 
g2.draw(new Line2D.Double(0, 0, 30, 40)); 
 
 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –6– 
Renderizado con Graphics2D 
 El proceso de renderizado de Java2D está controlado 
por el objeto Graphics2D 
 Renderizado=proceso de generar una representación 
(imagen) a partir de un modelo 
 Los atributos de un objeto Graphics2D o 
características contextuales son a su vez objetos (un 
atributo contextual puede ser por ejemplo, el tamaño 
del pincel con que se dibuja una línea recta) 
 El conjunto de estos atributos es lo que conforma el 
contexto del objeto Graphics2D. 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –7– 
Contexto de dibujo 
 Para dibujar un objeto gráfico, se establece el 
contexto en que se realizará el renderizado 
 Los atributos de estado que conforman el contexto y 
que pueden modificarse son los siguientes: 
 Variar la anchura del pincel. 
 Definir colores o patrones de relleno para las figuras. 
 Delimitar un área concreta a renderizar (clipping path). 
 Trasladar, rotar, reducir o ampliar objetos cuando son renderizados. 
 Especificar la forma en que se componen las figuras superpuestas. 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –8– 
Contexto de dibujo 
 Cuando Graphics2D va a realizar un operación de 
renderizado simple, tal como dibujar un rectángulo, 
un texto o una imagen, lo hace en base a un contexto 
determinado. 
 El contexto por defecto: trazo negro de 1 punto de 
ancho en el caso de las figuras geométricas. 
public void paint (Graphics g) { 
Graphics2D g2 = (Graphics2D)g; 
Rectangle2D r2 = new Rectangle2D.Float(75, 50, 100, 25); 
Stroke pincel = new BasicStroke(4.0f, BasicStroke.CAP_ROUND, 
BasicStroke.JOIN_MITER); 
g2.setStroke(pincel); 
g2.draw(r2); 
} 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –9– 
Clases Java2D 
 Entre las clases e interfaces más importantes, 
incluyendo las utilizadas por el contexto, podemos 
citar las siguientes (contenidas en los paquetes 
java.awt y java.awt.geom) 
 Interfaces: 
 Composite: define métodos para realizar composiciones de 
 dibujos. Entre otras cosas permite definir transparencias. 
 Paint: extiende a Transparency y define la forma en que se 
construyen las tramas de color durante las operaciones draw() y 
fill(). 
 Stroke: permite a Graphics2D generar un objeto Shape que 
representa el contorno de la figura que se quiere dibujar 
 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –10– 
Clases Java2D (I) 
 Clases: 
 AffineTransform: representa una transformación en 2D: 
traslación, inversión, rotación, etc. 
 AlphaComposite: implementa a Composite. Gestiona la 
composición alfa (transparencias) básica para las figuras, textos 
e imágenes. 
 BasicStroke: implementa a Stroke. Define el estilo del pincel 
que se aplica al dibujar el contorno de una figura. 
 Color: implementa a Paint. Define por ejemplo el color del 
relleno o del contorno al dibujar una figura. 
 GradientPaint: implementa a Paint. Define un patrón de 
relleno 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –11– 
Clases Java2D (II) 
 Clases: 
 Graphics2D: extiende a la clase Graphics. Es la clase 
fundamental para el renderizado 2D. 
 TexturePaint: define un patrón de relleno complejo al rellenar 
una figura. Este patrón -también llamado textura- está 
almacenado en un objeto de tipo BufferedImage. 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –12– 
El sistema de coordenadas de Java2D 
 Los objetos Java 2D se ubican 
 en un plano definido por coordenadas 
 Cartesianas XY 
 Java2D mantiene dos sistemas de coordenadas: 
coordenadas de usuario (user space) y coordenadas 
de dispositivo (device space): 
 El sistema de coordenadas de usuario es totalmente 
independiente del dispositivo final en el que se vaya a hacer el 
renderizado de los gráficos. 
 Java2D ejecuta automáticamente las conversiones entre los dos 
sistemas de coordenadas en el momento en que se realiza el 
renderizado real sobre un dispositivo. 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –13– 
Coordenadas de usuario 
 El origen de las coordenadas (0,0) de usuario está 
situado en la esquina superior izquierda del objeto 
Graphics2D. 
 A medida que se incrementa la x (primer valor de la 
coordenada) habrá un desplazamiento hacia la 
derecha y a medida que se incrementa la y (segundo 
valor de la coordenada) habrá un desplazamiento 
hacia abajo. 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –14– 
Coordenadas de dispositivo 
 En la tabla siguiente, a modo de resumen, se 
muestran las clases que intervienen en el sistema de 
coordenadas: 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –15– 
Figuras geométricas en Java2D 
 Java2D proporciona varias clases que representan 
objetos geométricos simples tales como puntos, 
líneas, curvas y rectángulos 
 Paquete java.awt.geom . 
 Rectangle2D, Line2D, Point2D ,Ellipse2D. 
 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –16– 
Figuras geométricas interface Shape 
 Por compatibilidad, 
las clases en versiones 
previas de JDK, como 
Rectangle, Point y 
Polygon, permanecen 
en el paquete 
java.awt y se pueden 
seguir usando. 
 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –17– 
Interfaz Shape 
 La interfaz Shape abstrae el comportamiento de una 
figura que puede dibujarse 
 Cualquier figura que implementa Shape posee un 
contorno (denominado path en inglés) 
 La interfaz Shape proporciona un mecanismo 
estándar para describir e interpretar el contorno de 
un objeto geométrico 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –18– 
Interfaz Shape 
 
 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –19– 
Figura Geométrica: Punto 
 Punto2D 
 Esta clase no dibuja nada, sino que es la representación de 
un
punto en Java2D. 
 Se pueden dibujar figuras a partir de puntos (ej líneas) 
 Ejemplo de creación de una línea 
public void paint (Graphics g) { 
Graphics2D g2 = (Graphics2D)g; 
g2.setStroke(new BasicStroke(3.0f)); 
Point2D p1 = new Point2D.Float(23.5f, 48.9f); 
Point2D p2 = new Point2D.Float(158.0f, 173.0f); 
Line2D l = new Line2D.Float(p1, p2); 
g2.draw(l); 
} 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –20– 
Figura Geométrica: Línea 
 Line2D 
 Constructores 
 Line2D.Float(float X1, float Y1, float X2, float Y2) 
 Line2D.Float(Point2D p1, Point2D p2) 
 Ejemplo 
public void paint (Graphics g) { 
super.paint(g); 
Graphics2D g2 = (Graphics2D)g; 
// Dibujo de la línea 
g2.setColor(Color.pink); 
g2.setStroke(new BasicStroke(3.0f)); 
Line2D linea = new Line2D.Float(50.0f, 50.0f, 200.0f, 200.0f); 
g2.draw(linea); 
} 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –21– 
Figura Geométrica: Rectángulo 
 Rectangle2D 
 El constructor especifica en los dos primeros parámetros la posición de la esquina 
superior izquierda con respecto al sistema de coordenadas de la ventana, y en los dos 
siguientes el ancho y largo respectivamente. 
 
public void paint (Graphics g) { 
super.paint(g); 
Graphics2D g2 = (Graphics2D)g; 
// Creación del Rectangle2D 
g2.setColor(Color.red); 
g2.setStroke(new BasicStroke(3.0f)); 
Rectangle2D r = new Rectangle2D.Float(100.0f, 75.0f, 50.0f, 100.0f); 
g2.draw(r); 
} 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –22– 
Tratamiento de texto con Java2D 
 En Java2D el texto es sencillamente un tipo especial 
de figura que puede ser representado y con el que se 
puede trabajar de diferentes maneras, más o menos 
parecidas a las disponibles con la interfaz Shape. 
 Una fuente de texto es un conjunto completo de 
caracteres con ciertas características gráficas 
distintivas 
 La fuente define la vista, tamaño y estilo 
característico (bold (negrita), italic (cursiva) o plain 
(normal)) con el que se puede dibujar una cadena de 
texto. 
 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –23– 
Trabajar con fuentes tipográficas 
 En Java2D para trabajar con texto hay que utilizar un 
objeto de la clase Font 
 Es necesario saber qué fuentes están disponibles en el 
sistema operativo 
for (Font f: raphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts()) 
 System.out.println(f.getName()+" - "+f.getFontName()+" - "+f.getFamily()); 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –24– 
Dibujar Texto 
 Ejemplo de dibujo de texto 
 
public void paint (Graphics g) { 
super.paint(g); 
Graphics2D g2 = (Graphics2D)g; 
g2.setColor(Color.blue); 
g2.setFont(new Font("Arial", Font.ITALIC, 24)); 
g2.drawString(“Viento en popa a toda vela…", 20, 60); 
} 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –25– 
Cargar una imagen 
 El método general usado para cargar una imagen 
desde una URL o desde un fichero es el método 
getImage() del paquete java.awt.Toolkit ( si no se usa 
buffer). 
 Para poder usar esta función hay que obtener antes el 
objeto Toolkit por defecto invocando a la función 
estática Toolkit.getDefaultToolkit(). 
 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –26– 
Ejemplo cargar una imagen 
public class Imagenes extends JFrame { 
public Imagenes() { 
super("Abrir Imagen"); 
} 
public void paint(Graphics g) { 
Graphics2D g2 = (Graphics2D)g; 
Image im = Toolkit.getDefaultToolkit().getImage(“lmagen.jpg"); 
g2.drawImage(im, 0, 20, this); 
} 
public static void main (String args[]) { 
Imagenes v = new Imagenes(); 
v.setDefaultCloseOperation(EXIT_ON_CLOSE); 
v.setSize(405,450); 
v.setVisible(true); 
} 
} 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –27– 
Cargar una imagen como BufferedImage 
 Java 2D soporta la carga de imágenes externas con 
Buffer mediante la clase ImageIO del paquete 
javax.imageio 
 Esta clase esta especializada en leer los formatos 
GIF,PNG,JPEG, BMP y WBMP 
 Ejemplo 
BufferedImage img = null; 
 try { img = ImageIO.read(new File(“map.jpg")); } 
catch (IOException e) { } 
 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –28– 
Dibujar sobre imágenes 
 La clase Image provee métodos para este propósito 
 public Graphics2D createGraphics(): este método 
sirve para representar una BufferedImage como una superficie 
de dibujo. 
 Los pasos a seguir son: 
 Crear un objeto BufferedImage nuevo. 
 Llamar a su método createGraphics(). 
 Establecer su configuración gráfica. 
 Dibujar sobre el objeto Graphics2D lo que se desee. 
 Pintar BufferedImage en el panel del JFrame. 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –29– 
Dibujar sobre imágenes 
 En el siguiente código se utiliza BufferedImage , se 
crea una Imágen con Java2D Graphics2D con el 
método createGraphics() 
 este Graphics2D se usa como superficie de dibujo 
sobre la que renderiza una imagen y luego se pintan 
unas líneas de color verde 
 El quid de la cuestión estriba en obtener el objeto 
Graphics2D asociado a BufferedImage. 
Gustavo Millán García 
UNIVERSIDAD PONTIFICIA DE SALAMANCA EN MADRID 
Departamento de Lenguajes y Sistemas Informáticos e Ingeniería del Software 
Página –30– 
Ejemplo dibujar sobre imágenes 
public void paint(Graphics g) { 
BufferedImage mImagen; 
Graphics2D g2 = (Graphics2D)g; 
Dimension d = getSize(); 
int a = d.width, l = d.height; 
mImagen = new BufferedImage(a, l, BufferedImage.TYPE_INT_RGB); 
Graphics2D gOculta = mImagen.createGraphics(); 
gOculta.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
RenderingHints.VALUE_ANTIALIAS_ON); 
Image im = Toolkit.getDefaultToolkit().getImage("neuschwanstein.jpg"); 
gOculta.drawImage(im,0,20,this); 
gOculta.setStroke(new BasicStroke(1.5f)); 
Color[] colors = { Color.red, Color.blue, Color.green }; 
gOculta.setPaint(Color.green); 
for (int i = -32; i < 40; i += 8) { 
gOculta.drawLine(i, i, a - i * 2, l - i * 2); 
gOculta.rotate(0.05f); 
} g2.drawImage(mImagen, 0, 0, this); 
} 
 
Aplicaciones 2015-2016 Campus/Patrón ActiveDomainObject.pdf
Asignatura programación de aplicaciones 
Patrón Active Domain Object 
 
Estructura 
 
 
Ejemplo de código 
 
public class Customer { 
 
 // SQL statements for data access. 
 private static final String QUERY 
 = "SELECT * FROM CUSTOMERS WHERE CUSTID = ?"; 
 
 private static final String INSERT 
 = "INSERT INTO CUSTOMERS " 
 + "(LAST, FIRST, ADDRESS, CITY, STATE, COUNTRY, " 
 + "ZIP, CUSTID) VALUES(?, ?, ?, ?, ?, ?, ?, ?)"; 
 
 private static final String UPDATE 
 = "UPDATE CUSTOMERS SET LAST
= ?, FIRST = ?, " 
 + "ADDRESS = ?, CITY = ?, STATE = ?, COUNTRY = ?, " 
 + "ZIP = ? WHERE CUSTID = ?"; 
 
 // The customer's data attributes. 
 private int id; 
 private String name; 
 private Address address; 
 
 // Indicates whether the data in the active domain 
 // object matches that in the database. 
 private boolean saved = false; 
 
 /** 
 Constructs a Customer object. This constructor is 
 intended for application code that adds new customers 
 to the database. It leaves the saved flag false to 
 indicate that the data is not stored in the database 
 yet. 
 */ 
 public Customer(int id, String name, Address address) { 
 this.id = id; 
 this.name = name; 
 this.address = address; 
 } 
 
 /** 
 Constructs a new Customer object. This constructor 
 is intended for application code to read information 
 for a single customer. 
 */ 
 public Customer(int id) throws DataException { 
 this.id = id; 
 
 try { 
 Connection connection 
 = ConnectionFactory.getConnection(); 
 PreparedStatement statement 
 = connection.prepareStatement(QUERY); 
 
 statement.setInt(1, id); 
 ResultSet resultSet = statement.executeQuery(); 
 resultSet.next(); 
 
 String lastName = resultSet.getString("LAST"); 
 String firstName = resultSet.getString("FIRST"); 
 String address = resultSet.getString("ADDRESS"); 
 String city = resultSet.getString("CITY"); 
 String state = resultSet.getString("STATE"); 
 String country = resultSet.getString("COUNTRY"); 
 String zip = resultSet.getString("ZIP"); 
 
 resultSet.close(); 
 statement.close(); 
 connection.close(); 
 
 initialize(id, lastName, firstName, address, 
 city, state, country, zip); 
 } 
 catch(SQLException e) { 
 throw new DataException("Unable to read customer " 
 + id, e); 
 } 
 } 
 
 /** 
 Constructs a Customer object. This constructor is 
 called only by CustomerList as it populates its 
 contents. 
 */ 
 public Customer(int id, 
 String lastName, 
 String firstName, 
 String address, 
 String city, 
 String state, 
 String country, 
 String zip) { 
 
 initialize(id, lastName, firstName, address, 
 city, state, country, zip); 
 } 
 
 /** 
 Initializes the contents of this object based on 
 physical data. This is the mapping of data from 
 its relational form to its domain object form. 
 */ 
 private void initialize(int id, 
 String lastName, 
 String firstName, 
 String address, 
 String city, 
 String state, 
 String country, 
 String zip) { 
 
 // Combine the first and last names, since 
 // that is how the application 
 // needs them. 
 StringBuffer buffer = new StringBuffer(); 
 buffer.append(lastName); 
 buffer.append(", "); 
 buffer.append(firstName); 
 name = buffer.toString(); 
 
 // Combine the city and state, since 
 // that is how the application 
 // needs them. 
 buffer = new StringBuffer(); 
 buffer.append(city); 
 buffer.append(", "); 
 buffer.append(state); 
 String cityState = buffer.toString(); 
 
 // Initialize the address. 
 this.address = new Address(); 
 this.address.setAddress1(address); 
 this.address.setCityState(cityState); 
 this.address.setCountry(country); 
 this.address.setPostalCode(zip); 
 
 // Set this to true, since this information 
 // was read from the database. 
 saved = true; 
 } 
 
 public String getName() { 
 return name; 
 } 
 
 public void setName(String name) { 
 this.name = name; 
 } 
 
 public Address getAddress() { 
 return address; 
 } 
 
 public void setAddress(Address address) { 
 this.address = address; 
 } 
 
 /** 
 Saves the customer information to the database. 
 This is the mapping of data from its domain object 
 form to its relational form. It uses the saved flag 
 to determine whether to insert new data or update 
 existing data. 
 */ 
 public void save() throws DataException 
 { 
 // Split the name into first and last, since 
 // the CUSTOMERS table stores these items in separate 
 // columns. 
 String first; 
 String last; 
 int comma = name.indexOf(','); 
 if (comma >= 0) { 
 first = name.substring(comma + 1).trim(); 
 last = name.substring(0, comma).trim(); 
 } 
 else { 
 first = ""; 
 last = name; 
 } 
 
 // Split the city and state, since the CUSTOMERS table 
 // stores these items in separate columns. 
 String cityState = address.getCityState(); 
 String city = ""; 
 String state = ""; 
 if (cityState != null) { 
 comma = cityState.indexOf(','); 
 if (comma >= 0) { 
 city = cityState.substring(0, comma).trim(); 
 state = cityState.substring(comma).trim(); 
 } 
 else { 
 city = cityState; 
 } 
 } 
 
 try { 
 Connection connection 
 = ConnectionFactory.getConnection(); 
 
 // If the customer information came from 
 // the database, then issue an update. 
 if (saved) { 
 PreparedStatement statement 
 = connection.prepareStatement(UPDATE); 
 statement.setString(1, last); 
 statement.setString(2, first); 
 statement.setString(3, address.getAddress1()); 
 statement.setString(4, city); 
 statement.setString(5, state); 
 statement.setString(6, address.getCountry()); 
 statement.setString(7, 
 address.getPostalCode()); 
 statement.setInt(8, id); 
 statement.executeUpdate(); 
 statement.close(); 
 } 
 
 // If the customer information did not 
 // come from the database, then issue an insert. 
 else { 
 PreparedStatement statement 
 = connection.prepareStatement(INSERT); 
 statement.setString(1, last); 
 statement.setString(2, first); 
 statement.setString(3, address.getAddress1()); 
 statement.setString(4, city); 
 statement.setString(5, state); 
 statement.setString(6, address.getCountry()); 
 statement.setString(7, 
 address.getPostalCode()); 
 statement.setInt(8, id); 
 statement.executeUpdate(); 
 statement.close(); 
 
 // Indicate that the information now exists 
 // in the database. 
 saved = true; 
 }

Continuar navegando