Skip to content

taller01

AlejandroCifuentes25 edited this page Aug 5, 2026 · 9 revisions

Módulo: venta de vehículo o repuesto

Problema: Facilita y centraliza la compra y venta de repuestos y carros en solo lugar de manera fácil y que se acomode las necesidades.

Solución arquitectónica:

Service Layer: Se creo PublicacionArticuloService para orquestar el flujo

Factory: El servicio necesita un validador documental y un notificador, pero no debe saber cuáles. Las Factories son el único punto del sistema que conoce las clases concretas, y eligen según variables de entorno.

Builder: CarroBuilder construye el objeto paso a paso con Fluent Interface (cada método devuelve self) y garantiza que build() solo devuelve instancias válidas.

Diagrama de clases

classDiagram
    class CrearArticuloView {
        <<Vista>>
        +template_name : string
        +form_class : CrearArticuloForm
        +success_url : string
        +service_factory : PublicacionArticuloService
        +form_valid(form) HttpResponse
    }

    class PublicacionArticuloService {
        <<Service Layer>>
        -validador : ValidadorDocumental
        -notificador : Notificador
        +crear_articulo(vendedor, datos) Carro
    }

    class CarroBuilder {
        <<Builder>>
        -vendedor : Vendedor
        -placa : string
        -marca : string
        -modelo : string
        -color : string
        -estado : string
        -kilometraje : int
        -precio : int
        -descripcion : string
        -documentos : DocumentoCarro[]
        +para_vendedor(vendedor) CarroBuilder
        +con_identificacion(placa, marca, modelo) CarroBuilder
        +con_caracteristicas(color, km, estado) CarroBuilder
        +con_precio(precio) CarroBuilder
        +con_descripcion(descripcion) CarroBuilder
        +con_documentos(documentos) CarroBuilder
        +build() Carro
    }

    class Carro {
        +placa : string
        +marca : string
        +modelo : string
        +estado : string
        +color : string
        +kilometraje : int
        +descripcion : string
        +precio : int
        +puntaje : float
    }

    class DocumentoCarro {
        +tipoDocumento : string
        +fechaExpedicion : date
        +fechaVencimiento : date
        +archivo : file
    }

    class ValidadorDocumental {
        <<interface>>
        +validar(placa, documentos) ResultadoValidacion
    }

    class ValidadorDocumentalMock {
        <<MOCK>>
        +validar(placa, documentos) ResultadoValidacion
    }

    class ValidadorDocumentalRunt {
        <<REAL>>
        -hoy : date
        +validar(placa, documentos) ResultadoValidacion
    }

    class Notificador {
        <<interface>>
        +notificar_publicacion(articulo)
    }

    class NotificadorConsola {
        <<MOCK>>
        +notificar_publicacion(articulo)
    }

    class NotificadorEmail {
        <<REAL>>
        +notificar_publicacion(articulo)
    }

    class ValidadorDocumentalFactory {
        <<Factory>>
        -registro : dict
        +crear(tipo) ValidadorDocumental
    }

    class NotificadorFactory {
        <<Factory>>
        -registro : dict
        +crear(tipo) Notificador
    }

    CrearArticuloView ..> PublicacionArticuloService : usa
    PublicacionArticuloService ..> CarroBuilder : usa
    PublicacionArticuloService --> ValidadorDocumental : valida con
    PublicacionArticuloService --> Notificador : notifica con
    CarroBuilder o-- DocumentoCarro : agrega
    CarroBuilder ..> Carro : crea

    ValidadorDocumentalFactory ..> ValidadorDocumental : crea
    ValidadorDocumentalFactory ..> ValidadorDocumentalMock : instancia
    ValidadorDocumentalFactory ..> ValidadorDocumentalRunt : instancia
    NotificadorFactory ..> Notificador : crea
    NotificadorFactory ..> NotificadorConsola : instancia
    NotificadorFactory ..> NotificadorEmail : instancia

    ValidadorDocumental <|.. ValidadorDocumentalMock : realiza
    ValidadorDocumental <|.. ValidadorDocumentalRunt : realiza
    Notificador <|.. NotificadorConsola : realiza
    Notificador <|.. NotificadorEmail : realiza
Loading

Decisiones de diseño

Decisión Justificación
build() no llama a .save() El dominio no debe conocer la persistencia. Devuelve un objeto en memoria y el Service decide cuándo y dentro de qué transacción guardarlo. Además permite probar las reglas sin base de datos (SimpleTestCase).
Se acumulan todos los errores Un raise en la primera falla obliga al vendedor a corregir de a un campo por intento. ArticuloInvalidoError lleva la lista completa.
Normaliza entradas (.upper(), .strip()) "abc123" y "ABC123" son la misma placa. Normalizar en el Builder evita duplicados en la base de datos.
Las reglas viven aquí y no en el Form Un ModelForm solo protege el flujo web. Estas reglas también aplican si el artículo se crea desde un comando o una API. El formulario valida formato; el Builder valida negocio.

Clone this wiki locally