En este artículo voy a resolver un caso donde explicare como aplicar el análisis orientado a objetos y la programación orientada a servicios.
PROYECTO PROPUESTO
La empresa STORE FOR MODELS necesita una aplicación para calcular el precio de venta de un producto, teniendo en cuenta el precio de costo, los gastos administrativos y la ganancia que se espera obtener.
Cuando la empresa compra un producto, lo que realiza es comprar un lote, y el precio que tiene es el precio del lote. Se estima que en un lote el 10% de productos se encuentre defectuoso, por lo tanto, solo el 90% podrá ser comercializado.
ANÁLISIS DEL REQUERIMIENTO
Julio Contreras, que se desempeña como analista funcional en la empresa, ha realizado el siguiente análisis de lo que debe ser el INPUT y OUTPUT del requerimiento.
El análisis se ilustra con un ejemplo.
Los datos correspondientes al INPUT serían:
- Nombre del producto: Pantalón de verano para damas
- Tamaño del lote: 1000 Unidades
- Precio del lote (Soles): 50,000.00
- Porcentaje de gastos administrativos (%): 25
- Porcentaje de ganancia por unidad (%): 200
Con estos datos se obtiene el siguiente OUTPUT:
- Unidades a comercializar: 900
- Gastos administrativos (Soles): 12,500.00
- Costo total del lote (Soles): 62,500.00
- Costo por unidad (Soles): 69.44 Soles
- Ganancia por unidad (Soles): 138.88 Soles
- Precio de Venta (Soles): 208.32 Soles
ARQUITECTURA DE LA APLICACIÓN
La arquitectura para desarrollar la aplicación será un desarrollo en capas:
| Capa Service: | Donde se tendrá el o los servicios necesarios para solucionar el requerimiento. |
| Capa View: | La capa view es la interfaz de la aplicación con el usuario, sirve para mostrar datos al usuario y para solicitar datos al usuario. |
| Capa Controller: | Esta capa es la responsable de gestionar las peticiones del usuario. Responde enviando a la vista los datos solicitados. |
ANÁLISIS Y DISEÑO DEL SERVICIO
La mejor alternativa es encapsular los datos del INPUT y OUTPUT en un objeto, de esta manera se desarrolla un solo servicio para procesar todos los datos y obtener los resultados esperados.
A la clase que encapsule todos los datos le llamaremos LoteModel.
A continuación se tiene el diseño del servicio:
DIAGRAMA DE SECUENCIA
A continuación tienes en diagrama de secuencia del proceso normal:
CODIGO FUENTE - EUREKA-CS-ORACLE-JDBC
En esta sección te presento un video de una aplicación CLIENTE-SERVIDOR desarrollada con Java y Oracle.
Tú tienes acceso al código fuente de esta aplicación, después del video tienes el enlace.
ANÁLISIS DE LA CLASE MODEL
Se trata de una clase que encapsula los datos del INPUT y el OUTPUT.
A continuación se tiene el script de esta clase:
package pe.egcc.preciodeventa.model;
public class LoteModel {
// INPUT
private String producto;
private Integer tamanio;
private Double precio;
private Double porcGasAdm;
private Double porcGanancia;
// OUTPUT
private Integer unidades;
private Double gasAdm;
private Double cosLote;
private Double cosUni;
private Double ganUni;
private double preVenta;
public LoteModel() {
}
public LoteModel(String producto, Integer tamanio,
Double precio, Double porcGasAdm, Double porcGanancia) {
this.producto = producto;
this.tamanio = tamanio;
this.precio = precio;
this.porcGasAdm = porcGasAdm;
this.porcGanancia = porcGanancia;
}
public String getProducto() {
return producto;
}
public void setProducto(String producto) {
this.producto = producto;
}
public Integer getTamanio() {
return tamanio;
}
public void setTamanio(Integer tamanio) {
this.tamanio = tamanio;
}
public Double getPrecio() {
return precio;
}
public void setPrecio(Double precio) {
this.precio = precio;
}
public Double getPorcGasAdm() {
return porcGasAdm;
}
public void setPorcGasAdm(Double porcGasAdm) {
this.porcGasAdm = porcGasAdm;
}
public Double getPorcGanancia() {
return porcGanancia;
}
public void setPorcGanancia(Double porcGanancia) {
this.porcGanancia = porcGanancia;
}
public Integer getUnidades() {
return unidades;
}
public void setUnidades(Integer unidades) {
this.unidades = unidades;
}
public Double getGasAdm() {
return gasAdm;
}
public void setGasAdm(Double gasAdm) {
this.gasAdm = gasAdm;
}
public Double getCosLote() {
return cosLote;
}
public void setCosLote(Double cosLote) {
this.cosLote = cosLote;
}
public Double getCosUni() {
return cosUni;
}
public void setCosUni(Double cosUni) {
this.cosUni = cosUni;
}
public Double getGanUni() {
return ganUni;
}
public void setGanUni(Double ganUni) {
this.ganUni = ganUni;
}
public double getPreVenta() {
return preVenta;
}
public void setPreVenta(double preVenta) {
this.preVenta = preVenta;
}
}
CAPA SERVICE
A continuación tienes la implementación de clase correspondiente a la capa de servicio:
package pe.egcc.preciodeventa.service;
import pe.egcc.preciodeventa.model.LoteModel;
public class LoteService {
public LoteModel procesarLote(LoteModel bean) {
// Variables
Integer unidades;
Double gasAdm, costoLote, cosUni, ganUni, preVenta;
// Proceso
unidades = (int) Math.round(bean.getTamanio() * 0.90) ;
gasAdm = bean.getPrecio() * ( bean.getPorcGasAdm() / 100 );
costoLote = bean.getPrecio() + gasAdm;
cosUni = costoLote / unidades;
ganUni = cosUni * (bean.getPorcGanancia() / 100.0);
preVenta = cosUni + ganUni;
// Preparar salida
bean.setUnidades(unidades);
bean.setGasAdm(dosDec(gasAdm));
bean.setCosLote(dosDec(costoLote));
bean.setCosUni(dosDec(cosUni));
bean.setGanUni(dosDec(ganUni));
bean.setPreVenta(dosDec(preVenta));
// Retorno
return bean;
}
private double dosDec(double valor){
valor = Math.round( valor * 100.0 );
valor = valor / 100.0;
return valor;
}
}
PRUEBA DEL SERVICIO
Es muy importante probar el servicio, de esta manera podemos hacer las correcciones si encontramos algún error.
La clase de prueba que he elaborado es la siguiente:
package pe.egcc.preciodeventa.prueba;
import pe.egcc.preciodeventa.model.LoteModel;
import pe.egcc.preciodeventa.service.LoteService;
public class Prueba01 {
public static void main(String[] args) {
// datos
String producto = "Pantalón de verano para damas";
int tamanio = 1000;
double precio = 50000.0;
double porcGasAdm = 25.0;
double porcGanancia = 200.0;
LoteModel bean = new LoteModel(producto, tamanio, precio, porcGasAdm, porcGanancia);
// Proceso
LoteService service = new LoteService();
bean = service.procesarLote(bean);
// Reporte
System.out.println("Unidades a comercializar: " + bean.getUnidades());
System.out.println("Gastos administrativos: " + bean.getGasAdm());
System.out.println("Costo del lote: " + bean.getCosLote());
System.out.println("Costo por unidad: " + bean.getCosUni());
System.out.println("Ganancia por unidad: " + bean.getGanUni());
System.out.println("Precio de venta: " + bean.getPreVenta());
}
}
El resultado es el siguiente:
run-single: Unidades a comercializar: 900 Gastos administrativos: 12500.0 Costo del lote: 62500.0 Costo por unidad: 69.44 Ganancia por unidad: 138.89 Precio de venta: 208.33
CAPA CONTROLLER
A continuación tienes el script de la clase controladora:
package pe.egcc.preciodeventa.controller;
import pe.egcc.preciodeventa.model.LoteModel;
import pe.egcc.preciodeventa.service.LoteService;
public class LoteController {
public LoteModel procesarLote(LoteModel bean) {
LoteService service = new LoteService();
return service.procesarLote(bean);
}
}
CAPA VIEW
A continuación tienes el formulario que se ha implementado:
Para programar el formulario ha sido necesario la implementación de dos métodos que sirven de soporte para su funcionamiento:
private void activarControles(boolean estado) {
// Botones
btnProcesar.setEnabled(estado);
btnLimpiar.setEnabled(!estado);
// Cuadros de texto
txtPorcGana.setEnabled(estado);
txtPorcGasAdm.setEnabled(estado);
txtPrecio.setEnabled(estado);
txtProducto.setEnabled(estado);
txtTamanio.setEnabled(estado);
}
private void limpiarForm() {
txtCosLote.setText("");
txtCosUni.setText("");
txtPorcGana.setText("");
txtPorcGasAdm.setText("");
txtPrecio.setText("");
txtPreVenta.setText("");
txtProducto.setText("");
txtTamanio.setText("");
txtUnidades.setText("");
txtGanUni.setText("");
txtGasAdm.setText("");
txtProducto.requestFocus();
}
Programación del botón Procesar:
// datos
String producto = txtProducto.getText();
int tamanio = Integer.parseInt(txtTamanio.getText());
double precio = Double.parseDouble(txtPrecio.getText());
double porcGasAdm = Double.parseDouble(txtPorcGasAdm.getText());
double porcGanancia = Double.parseDouble(txtPorcGana.getText());
LoteModel bean = new LoteModel(producto, tamanio, precio, porcGasAdm, porcGanancia);
// Proceso
LoteController control = new LoteController();
bean = control.procesarLote(bean);
// Reporte
txtUnidades.setText("" + bean.getUnidades());
txtGasAdm.setText("" + bean.getGasAdm());
txtCosLote.setText("" + bean.getCosLote());
txtCosUni.setText("" + bean.getCosUni());
txtGanUni.setText("" + bean.getGanUni());
txtPreVenta.setText("" + bean.getPreVenta());
activarControles(false);
Programación del botón Limpiar:
activarControles(true); limpiarForm();
Finalmente, espero que este ejemplo te sea útil para entender la programación en capas y programación orientada a servicios.
CODIGO FUENTE - EUREKA-WEB-MYSQL-SPRING
En esta sección te presento un video de una aplicación web desarrollada SPRING FRAMEWORK y MYSQL.
Tú tienes acceso al código fuente de esta aplicación, después del video tienes el enlace.






No hay comentarios:
Publicar un comentario