ADOO - CASO ILUSTRATIVO

ANÁLISIS Y DISEÑO ORIENTADO A OBJETOS - CASO ILUSTRATIVO
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