Ejemplo de desarrollo - Escuela de Ingeniería Industrial

Anuncio
Problema
™ Se deberá desarrollar un sistema que permita gestionar las Ordenes de
Despacho (O/D) de un pequeño distribuidor de productos.
Particularmente el sistema deberá permitir generar, consultar,
modificar y eliminar O/D, junto con todos los otros datos asociados.
Ejemplo (incompleto) de desarrollo de una
aplicación en Java
™ Las O/D son documentos que contienen un número identificador, los
datos del cliente al cual van dirigidas y una lista de productos con sus
cantidades y precios a despachar.
™ Se desea que al momento de generar la O/D, el sistema utilice los
datos almacenados previamente relativos a clientes y productos. La
aplicación, por lo tanto, deberá mantener también estos datos.
Franco Guidi Polanco
Escuela de Ingeniería Industrial
Pontificia Universidad Católica de Valparaíso, Chile
[email protected]
Franco Guidi Polanco
Problema (cont.)
Modelo de Análisis: primera aproximación
™ Ejemplo de una O/D:
ACME, INC.
O/D
número
precio total
impuesto
Nº 0162353
ORDEN DE DESPACHO
0..*
RUT Cliente: 1.111.111-3 Razón Social: COYOTE Y ASOCIADOS
Dirección: Camino Troncal 2734, Villa Alemana
Teléfono: 64654522
Detalle
Código Nombre
L323 Lanzacohetes
M001 Maíz para correcaminos
P1189 Pintura invisible
Franco Guidi Polanco
2
Unidad
Cantidad Precio unit Total ($)
un
kg
galón
2
50
2
$
$
145.000
Total:
$
159.500
1..1 rut
razón social
dirección
teléfono
Producto en O/D
cantidad
0..*
Producto
código
nombre
unidad
precio unitario
15.500
31.000
2.000 100.000
7.000 14.000
Subtotal:
Impuesto (10%):
Cliente
0..*
14.500
3
Franco Guidi Polanco
ACME, INC.
Nº 0162353
ORDEN DE DESPACHO
RUT Cliente: 1.111.111-3 Razón Social: COYOTE Y ASOCIADOS
Dirección: Camino Troncal 2734, Villa Alemana
Teléfono: 64654522
Detalle
Código Nombre
L323 Lanzacohetes
M001 Maíz para correcaminos
P1189 Pintura invisible
Unidad
Cantidad Precio unit Total ($)
un
kg
galón
2
50
2
15.500 31.000
2.000 100.000
7.000 14.000
Subtotal:
Impuesto (10%):
$
$
145.000
Total:
$
159.500
14.500
4
Modelo de Análisis: modelo refinado I
Modelo de Análisis: modelo refinado II
™ Notamos relación TODO-PARTE entre O/D y Producto en
O/D
O/D
número
precio total
impuesto
0..*
1..1
™ Notamos que una actualización en los precios de producto,
modificaría la información de O/D registradas. Luego es
necesario registrar el precio unitario en el Producto en O/D:
Cliente
rut
razón social
dirección
teléfono
O/D
número
precio total
impuesto
0..*
0..*
Producto en O/D
0..*
1..1
cantidad
Producto en O/D
cantidad
precio unitario
Modelo de Análisis: comentarios respecto del
modelo refinado II
código
1..1 nombre
unidad
precio unitario
Franco Guidi Polanco
6
:O/D
número=162353
precio total=159500
impuesto=10%
:Producto en O/D
cantidad=2
precio unitario=15500
Cliente
1..1 rut
:Producto en O/D
razón social
dirección
teléfono
cantidad=50
precio unitario=2000
:Producto en O/D
cantidad=2
precio unitario=7000
Franco Guidi Polanco
0..*
™ Diagrama de objetos:
Cliente en O/D
dirección
teléfono
Producto
¿Cómo se ve el modelo en un caso?
™Razonamiento análogo al anterior, nos
puede conducir a cuestionar la relación
entre O/D y Cliente: ¿Qué pasa si se
actualizan los datos del cliente? (ej.
cambio de teléfono?)
0..*
rut
razón social
dirección
teléfono
0..*
código
nombre
unidad
precio unitario
5
1..1 1..1
Cliente
Producto
Franco Guidi Polanco
O/D
número
precio total
impuesto
1..1
7
Franco Guidi Polanco
:Cliente
rut=“1.111.111-3”
razón social= “COYOTE Y ASOC.”
dirección=“camiino Troncal…”
teléfono=“64654522”
:Producto
código=“L323”
nombre=“Lanzacohetes”
unidad=“un”
precio unitario=15500
:Producto
código=“M001”
nombre=“Maíz para correcaminos”
unidad=“kg”
precio unitario=2000
:Producto
código=“P1189”
nombre=“Pintura invisible”
unidad=“galón”
precio unitario=7000
8
Modelo de Diseño: consideraciones a la primera
aproximación
Modelo de Diseño: primera aproximación
™ ¿El precio total de la O/D será almacenado en una variable de instancia
o calculado sumando los precios unitarios de los Productos en O/D?...
No importa, encapsulemos el proceso de obtención dentro de un
método.
OrdenDespacho
0..*
número
impuesto
1..1
getPrecioTotal()
ƒ Incluyendo como parámetro del constructor de O/D una referencia a
Cliente. Podemos, incluso, generar una excepción en la instanciación de
O/D si la referencia a cliente pasada por parámetro tiene valor null.
ƒ Si admitimos un método setCliente, verificando que este método no
contenga una referencia null.
Cliente
rut
razónSocial
dirección
teléfono
OrdenDespacho
número
impuesto
Producto
0..*
Producto en OD
cantidad
precioUnitario
™ El modelo establece que una O/D debe estar asociada siempre a un
Cliente ¿Podemos forzar esto?
™ Sí:
setCliente(c:Cliente)
getPrecioTotal()
OD(cliente:Cliente)
código
1..1 nombre
unidad
precioUnitario
0..*
Franco Guidi Polanco
9
Modelo de Diseño: segunda versión
número: String
impuesto: float
0..*
ProductoEnOD
Franco Guidi Polanco
Cliente
rut
razónSocial
dirección
teléfono
setCliente(c:Cliente){
if(c != null)
cliente = c;
}
Franco Guidi Polanco
10
™Navegabilidad:
OrdenDespacho
-número: String
-impuesto: float
setCliente(c:Cliente)
getCliente(): Cliente
getNumero(): int
getPrecioTotal(): int
OD(número:int, cliente:Cliente
impuesto:float)
cantidad:int
precioUnitario:int
setCantidad(c:int)
getCantidad():int
setPrecioUnitario(p:int)
getPrecioUnitario():int
1..1
Modelo de Diseño: tercera versión
™ Agregamos métodos y constructores
OrdenDespacho
0..*
0..*
0..*
1..1
Producto
código:String
nombre:String
unidad:String
precioUnitario:int
getCódigo():String
getNombre():String
getUnidad():String
1..1 setPrecioUnitario(p:int)
getPrecioUnitario()String
Producto(cod:String,
nom:String, un:String,
pu:int)
Cliente
rut:String
razónSocial:String
dirección:String
teléfono:String
getRut():String
getRazónSocial():String
getDirección():String
getTeléfono():String
Cliente(rut:String,rs:String,
dir:String,tel:String)
setCliente(c:Cliente)
getCliente(): Cliente
getNumero(): int
getPrecioTotal(): int
OD(número:int, cliente:Cliente
impuesto:float)
0..*
ProductoEnOD
-cantidad:int
-precioUnitario:int
setCantidad(c:int)
getCantidad():int
setPrecioUnitario(p:int)
getPrecioUnitario():int
11
Franco Guidi Polanco
0..*
0..*
1..1
Producto
-código:String
-nombre:String
-unidad:String
-precioUnitario:int
getCódigo():String
getNombre():String
getUnidad():String
1..1 setPrecioUnitario(p:int)
getPrecioUnitario()String
Producto(cod:String,
nom:String, un:String,
pu:int)
Cliente
-rut:String
-razónSocial:String
-dirección:String
-teléfono:String
getRut():String
getRazónSocial():String
getDirección():String
getTeléfono():String
Cliente(rut:String,rs:String,
dir:String,tel:String)
12
Modelo de Diseño: cuarta versión
OrdenDespacho
™ ¿Cómo agregamos productos a la
O/D?
OrdenDespacho
-número: String
-impuesto: float
setCliente(c:Cliente)
getCliente(): Cliente
getNumero(): int
getPrecioTotal(): int
addProducto(p:Producto,cant:int)
OD(número:int, cliente:Cliente
impuesto:float)
0..*
Modelo de Diseño: cuarta versión (completa)
-número: String
-impuesto: float
setCliente(c:Cliente)
0..*
1..1
getCliente(): Cliente
getNumero(): int
getPrecioTotal(): int
addProducto(p:Producto,cant:int)
Producto
OD(número:int, cliente:Cliente
-código:String
impuesto:float)
-nombre:String
-unidad:String
-precioUnitario:int
0..*
getCódigo():String
getNombre():String
ProductoEnOD
getUnidad():String
-cantidad:int
0..*
1..1 setPrecioUnitario(p:int)
-precioUnitario:int
getPrecioUnitario()String
setCantidad(c:int)
Producto(cod:String,
getCantidad():int
nom:String, un:String,
setPrecioUnitario(p:int)
pu:int)
getPrecioUnitario():int
Producto
ProductoEnOD
-cantidad:int
-precioUnitario:int
setCantidad(c:int)
getCantidad():int
setPrecioUnitario(p:int)
getPrecioUnitario():int
0..*
-código:String
-nombre:String
-unidad:String
-precioUnitario:int
1..1 getCódigo():String
getNombre():String
getUnidad():String
setPrecioUnitario(p:int)
getPrecioUnitario()String
Franco Guidi Polanco
13
¿Cómo implementamos las asociaciones en Java?
OrdenDespacho
setCliente(c:Cliente)
0..*
getCliente(): Cliente
getNumero(): int
getPrecioTotal(): int
addProducto(p:Producto,cant:int)
OD(número:int, cliente:Cliente
impuesto:float)
public class OrdenDespacho{
private String número;
private float impuesto;
private Cliente cliente;
…
}
Franco Guidi Polanco
1..1
14
¿Cómo implementamos las asociaciones en Java?
-número: String
-impuesto: float
-rut:String
-razónSocial:String
-dirección:String
-teléfono:String
getRut():String
getRazónSocial():String
getDirección():String
getTeléfono():String
Cliente(rut:String,rs:String,
dir:String,tel:String)
setCliente(c:Cliente)
getCliente(): Cliente
getNumero(): int
getPrecioTotal(): int
addProducto(p:Producto,cant:int)
OD(número:int, cliente:Cliente
impuesto:float)
0..*
™Implementación de la
asociación O/D con
Cliente
ProductoEnOD
-cantidad:int
-precioUnitario:int
setCantidad(c:int)
getCantidad():int
setPrecioUnitario(p:int)
getPrecioUnitario():int
15
getRut():String
getRazónSocial():String
getDirección():String
getTeléfono():String
Cliente(rut:String,rs:String,
dir:String,tel:String)
Franco Guidi Polanco
OrdenDespacho
Cliente
-número: String
-impuesto: float
Cliente
-rut:String
-razónSocial:String
-dirección:String
-teléfono:String
Franco Guidi Polanco
™ Implementaciones alternativas
de la asociación de O/D y
Producto en O/D (entre otras)
public class OrdenDespacho{
private String número;
private float impuesto;
private Cliente cliente;
private ProductoEnOD[] productoEnOD;
…
}
import java.util.Vector;
public class OrdenDespacho{
private String número;
private float impuesto;
private Cliente cliente;
private Vector productoEnOD;
…
}
16
¿Cómo implementamos las asociaciones en Java?
ProductoEnOD
-cantidad:int
-precioUnitario:int
setCantidad(c:int)
getCantidad():int
setPrecioUnitario(p:int)
getPrecioUnitario():int
Producto
-código:String
-nombre:String
0..* 1..1
-unidad:String
-precioUnitario:int
getCódigo():String
getNombre():String
getUnidad():String
setPrecioUnitario(p:int)
getPrecioUnitario()String
Producto(cod:String,
nom:string, un:string,
pu:int)
™ Implementación
de asociación
entre
ProductoEnOD y
Producto
™ ¿Cómo mantenemos los datos de O/D,
Clientes y Productos en la aplicación?
™ Podríamos manejarlos en arreglos o
Vectores:
public class SistemaOrdenes{
public static void main(String[] arg){
…
Cliente[] cliente = new Cliente[10000];
OD[] od = new OD[10000];
Producto[] = new Producto[10000];
…
}
}
public class ProductoEnOD{
private int cantidad;
private int precioUnitario;
private Producto producto;
…
}
Franco Guidi Polanco
17
Observación a la utilización de arreglos
™ La aplicación es
responsable de manejar
los arreglos (Clientes, O/D
y Productos):
ƒ identificar posiciones
disponibles
ƒ no acceder a posiciones
inexistentes
ƒ realizar búsquedas
ƒ etc.
Franco Guidi Polanco
Franco Guidi Polanco
18
Conveniencia de utilizar colecciones
public class SistemaOrdenes{
public static void main(String[] arg){
…
Cliente[] cliente = new Cliente[10000];
OD[] od = new OD[10000];
Producto[] = new Producto[10000];
…
// agregar un Cliente
for(int i=0;i<cliente.length;i++){
if( cliente[i] == null )
… etc
}
Modelo de Diseño: ¿qué falta?
™ Es conveniente utilizar clases que permitan mantener datos
de Clientes, O/D y Productos:
listaOD:Lista
Nº01:OD
Nº02:OD
Nº99:OD
listaProductos:Lista
// agregar un Producto
for(int i=0;i<producto.length;i++){
if( producto[i] == null )
… etc
…
}
Perno:Producto
Golilla:Producto
listaClientes:Lista
Inducap:Cliente
19
Franco Guidi Polanco
Acme:Cliente
Insumor:Cliente
20
Implementación de Listas
Implementación de Listas
public abstract class Lista{
private Object[] elem = new Object[10000];
private int posLibre = 0;
Lista
{abstract}
-elemento:Object
-posLibre:int
agregar(o:Object)
buscar(clave:String):Object {abstract}
eliminar(clave:String)
public boolean agregar(Object o){
if(posLibre < elem.length){
elem[posLibre] = o;
posLibre++;
return true;
}
return false;
}
™La implementación de estas colecciones reduce las
responsabilidades de la aplicación:
public class SistemaOrdenes{
public static void main(String[] arg){
…
ListaClientes listaCliente = new ListaClientes();
ListaOD listaOd = new ListaOD();
ListaProducto listaProducto= new ListaProductos();
…
public abstract buscar(String clave);
public boolean eliminar(Object o){
for(int i:=0; i<posLibre; i++ ){
if( elem[i]==o){
...
ListaOD
ListaClientes
ListaProductos
buscar(clave:String):Object
buscar(clave:String):Object
buscar(clave:String):Object
Franco Guidi Polanco
// agregar un Cliente
listaCliente.agregar( nuevoCliente );
}
21
Finalmente nuestro modelo:
ƒ Respuesta: Sí.
ƒ Pregunta ¿Cómo? Con uso adecuado de abstracciones
(ver principio de inversión de dependencia). Tarea.
ListaProductos
0..*
OrdenDespacho
0..*
1..1
ProductoEnOD
™Además podríamos utilizar “Generics” de Java.
™Se sugiere revisar además el Java Collections
Framework.
Cliente
0..*
0..*
0..*
22
™¿Podríamos definir un único tipo de lista para
manipular todas las colecciones?
ListaClientes
0..*
Franco Guidi Polanco
Refinamiento sucesivo
Lista
{abstract}
ListaOD
// agregar un Producto
listaProducto.agregar( nuevoProducto );
}
1..1
Producto
™ ¿Qué diferencia existe entre las clases indicadas en celeste
y las restantes clases?
Franco Guidi Polanco
23
Franco Guidi Polanco
24
Descargar