El diagrama no es todavía el programa
El SCORM anterior nos dejó dos miradas sobre el mismo problema: un modelo conceptual para comprender el negocio y un modelo de diseño para acercarnos a Java.


DetalleVenta, porque pertenece a esa operación, no al producto del catálogo en general.Conservamos los diagramas originales. Para los ejemplos que siguen elegiremos determinadas firmas Java; son decisiones de implementación y no datos nuevos del modelo conceptual.
La clase describe; el objeto existe
Una clase define qué información y operaciones tienen los objetos de un mismo tipo. Un objeto es una instancia concreta, con valores propios.
- codigo = 101
- nombre = "Mafalda 1"
- precio = 450.0
- stock = 8
- codigo = 102
- nombre = "El Eternauta"
- precio = 790.0
- stock = 3
Ambos tienen el mismo tipo y la misma estructura, pero no son el mismo objeto ni tienen el mismo estado.
public class Producto {
private long codigo;
private String nombre;
private double precio;
private int stock;
public Producto(long codigo, String nombre, double precio, int stock) {
this.codigo = codigo;
this.nombre = nombre;
this.precio = precio;
this.stock = stock;
}
}El constructor recibe los valores iniciales. this.codigo se refiere al atributo del objeto; codigo es el parámetro recibido.
Los atributos representan información del dominio
Producto
El ejemplar del catálogo tiene código, nombre, precio y stock. El stock representa unidades disponibles, no unidades compradas en una venta concreta.
DetalleVenta
Registra qué producto figura en una venta, cuántas unidades se compraron y qué precio unitario se aplicó.
| Entidad | Atributos principales | ¿Por qué? |
|---|---|---|
Cliente | cédula, nombre, correo | Identificar al comprador. |
Venta | número, fecha, cliente, detalles | Representar una transacción. |
Producto | código, nombre, precio, stock | Describir el catálogo. |
DetalleVenta | producto, cantidad, precioUnitario | Representar cada renglón de la compra. |
¿Qué debe saber hacer cada clase?
No diseñamos clases únicamente para guardar datos. También distribuimos responsabilidades: acciones coherentes con lo que cada objeto representa.
Producto
Informar su precio y stock; permitir modificaciones controladas de sus datos.
DetalleVenta
Calcular el subtotal del renglón: cantidad por precio unitario.
Venta
Conservar sus detalles y calcular el total sumando los subtotales.
public class DetalleVenta {
private Producto producto;
private int cantidad;
private double precioUnitario;
public DetalleVenta(Producto producto, int cantidad, double precioUnitario) {
this.producto = producto;
this.cantidad = cantidad;
this.precioUnitario = precioUnitario;
}
public double calcularSubtotal() {
double subtotal = cantidad * precioUnitario;
return subtotal;
}
}precioUnitario se conserva en el detalle, incluso si luego cambia el precio del catálogo. Así podemos representar el precio utilizado en esa venta.Atributos privados y operaciones públicas
Declarar los atributos private evita que otra clase modifique directamente el estado. Exponemos métodos públicos para consultar o cambiar lo que corresponda.
Sin control
Otra clase modifica un precio directamente y puede introducir valores incorrectos.
producto.precio = -50;Con encapsulamiento
El objeto decide qué operación pública ofrece y qué condiciones aplica.
producto.setPrecio(450);public long getCodigo() {
return codigo;
}
public String getNombre() {
return nombre;
}
public double getPrecio() {
return precio;
}
public int getStock() {
return stock;
}
public void setPrecio(double nuevoPrecio) {
if (nuevoPrecio >= 0 && Double.isFinite(nuevoPrecio)) {
this.precio = nuevoPrecio;
}
}El ejemplo introduce una comprobación pequeña para ilustrar la idea. Más adelante veremos una capa de servicio que concentrará las reglas de negocio de la aplicación; no debemos confundir ambas responsabilidades.
Los objetos colaboran mediante referencias
En Java, una relación entre objetos puede implementarse conservando una referencia a otro objeto. Cuando una venta tiene varios detalles, podemos usar una colección de referencias.
Una venta, un cliente
Un campo Cliente cliente identifica al comprador de esa venta.
Una venta, varios detalles
Una lista permite registrar diferentes productos y cantidades dentro de una misma venta.
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
public class Venta {
private int numero;
private LocalDate fecha;
private Cliente cliente;
private List<DetalleVenta> detalles;
public Venta(int numero, LocalDate fecha, Cliente cliente) {
this.numero = numero;
this.fecha = fecha;
this.cliente = cliente;
this.detalles = new ArrayList<>();
}
public void agregarDetalle(DetalleVenta detalle) {
detalles.add(detalle);
}
public double calcularTotal() {
double total = 0;
for (DetalleVenta detalle : detalles) {
total += detalle.calcularSubtotal();
}
return total;
}
}Date. Aquí usamos LocalDate, disponible en Java moderno, para representar una fecha sin hora. Es una elección de implementación, no una modificación del diagrama original.La historia completa, en objetos
Supongamos que Lucía compra dos ejemplares de «Mafalda 1» y uno de «El Eternauta». Creamos los productos, un cliente, la venta y sus detalles.
import java.time.LocalDate;
public class Main {
public static void main(String[] args) {
Producto mafalda = new Producto(101, "Mafalda 1", 450, 8);
Producto eternauta = new Producto(102, "El Eternauta", 790, 3);
Cliente lucia = new Cliente(49876543L, "Lucía Pérez", "lucia@ejemplo.com");
Venta venta = new Venta(25, LocalDate.of(2026, 10, 25), lucia);
DetalleVenta d1 = new DetalleVenta(mafalda, 2, 450);
DetalleVenta d2 = new DetalleVenta(eternauta, 1, 790);
venta.agregarDetalle(d1);
venta.agregarDetalle(d2);
System.out.println("Total: $" + venta.calcularTotal());
}
}public class Cliente {
private long cedula;
private String nombre;
private String correo;
public Cliente(long cedula, String nombre, String correo) {
this.cedula = cedula;
this.nombre = nombre;
this.correo = correo;
}
}El Main es solo un ejemplo para visualizar la colaboración entre objetos. Todavía no hay Swing, DAO ni base de datos; esos componentes aparecerán más adelante cuando hagan falta.
double, como en el modelo que estamos trabajando. En sistemas monetarios de producción es preferible BigDecimal.Del modelo OO a responsabilidades concretas
Comprobación rápida
Si una venta contiene tres productos diferentes, ¿qué objeto debería calcular el importe de cada renglón?
Venta y DetalleVenta: nombre de clase, dos responsabilidades y sus colaboradores. Acompáñala con un ejemplo de objeto concreto de cada una.Lo siguiente: profundizaremos en encapsulamiento, relaciones y colecciones, y veremos cómo las decisiones OO nos permiten construir programas más fáciles de ampliar.
PROGRAMACIÓN AVANZADA