Diagrama de clases — Hotel MDJ - MiguelAngelMarinMejia1/ArquitecturaDeSoftware-Proyecto GitHub Wiki

Evolución del diagrama entregado en el Taller 01, aplicado al sistema implementado en la Entrega 1.

Cambios respecto al diagrama original:

  1. Aparece User, la entidad de autenticación, unida a Customer por una asociación opcional en ambos extremos: un huésped puede reservar sin cuenta, y una cuenta puede pertenecer a personal del hotel sin ser huésped.
  2. Customer suma country, marketing_consent y la operación linkAccount().
  3. Reservation separa numAdults y numChildren, y guarda confirmationCode, subtotal, taxes y totalAmount.
  4. RoomType suma bedType.
  5. Payment suma gatewayReference.
  6. Los nombres coinciden con los del código, de modo que el diagrama pueda contrastarse directamente contra la implementación.
classDiagram
    class User {
        -username: String
        -password: String
        -lastLogin: Date
        -isActive: bool
        +checkPassword(raw: String) bool
        +setPassword(raw: String) void
    }

    class Customer {
        -idCustomer: int
        -firstName: String
        -lastName: String
        -email: String
        -phone: String
        -country: String
        -documentId: String
        -marketingConsent: bool
        -createdAt: Date
        +register() bool
        +updateProfile() void
        +getReservationHistory() List~Reservation~
        +linkAccount(user: User) bool
    }

    class Reservation {
        -idReservation: int
        -checkInDate: Date
        -checkOutDate: Date
        -createdAt: Date
        -numAdults: int
        -numChildren: int
        -specialRequests: String
        -status: String
        -confirmationCode: String
        -subtotal: float
        -taxes: float
        -totalAmount: float
        +calculateTotal() float
        +countNights() int
        +confirm() bool
        +cancel() bool
        +changeDates(newCheckIn: Date, newCheckOut: Date) bool
        +generateConfirmationCode() String
    }

    class Room {
        -number: String
        -floor: int
        -status: String
        -isActive: bool
        +checkAvailability(checkIn: Date, checkOut: Date) bool
        +changeStatus(newStatus: String) void
    }

    class RoomType {
        -name: String
        -description: String
        -maxCapacity: int
        -bedType: String
        -basePricePerNight: float
        +calculateSeasonalPrice(date: Date) float
        +fitsGuests(adults: int, children: int) bool
    }

    class Payment {
        -idPayment: int
        -amount: float
        -date: Date
        -paymentMethod: String
        -status: String
        -gatewayReference: String
        +processPayment() bool
        +refund() bool
    }

    class Invoice {
        -idInvoice: int
        -issueDate: Date
        -subtotal: float
        -taxes: float
        -total: float
        +generateInvoice() void
        +sendByEmail() bool
    }

    Customer "0..1" -- "0..1" User : tiene cuenta
    Customer "1" --> "0..*" Reservation : realiza
    Reservation "1..*" --> "1..*" Room : reserva
    Room "0..*" --> "1" RoomType : es de tipo
    Reservation "1" --> "0..1" Payment : genera
    Payment "1" --> "0..1" Invoice : produce

Dónde se implementa cada operación

El diagrama declara el comportamiento del dominio. En el código ese comportamiento no vive dentro de los modelos, porque el enunciado penaliza en un 50 % el criterio SOLID si aparece lógica de negocio en métodos de un Model que no sean de persistencia. Las operaciones se implementan en las capas de dominio y de aplicación:

Operación del diagrama Implementada en
Customer.register() services.py → CustomerService.get_or_create_profile()
Customer.updateProfile() services.py → CustomerService.get_or_create_profile()
Customer.getReservationHistory() selectors.py
Customer.linkAccount() services.py → CustomerService.link_to_account()
Reservation.calculateTotal() domain/policies.py → PricingPolicy.quote()
Reservation.countNights() domain/policies.py → PricingPolicy.nights_between()
Reservation.confirm() services.py → ReservationService.create_reservation()
Reservation.cancel() services.py → ReservationService.cancel_reservation()
Reservation.changeDates() services.py → ReservationService
Reservation.generateConfirmationCode() domain/codes.py → ConfirmationCodeGenerator
Room.checkAvailability() selectors.py → is_room_available()
Room.changeStatus() services.py → ReservationService
RoomType.calculateSeasonalPrice() domain/policies.py → SeasonalPricingPolicy.rate_for()
RoomType.fitsGuests() domain/policies.py → CapacityPolicy.fits()
Payment.processPayment() services.py → PaymentService.charge()
Payment.refund() services.py → PaymentService
Invoice.generateInvoice() services.py → InvoiceService.issue()
Invoice.sendByEmail() infra/notifications.py → EmailNotifier

Nota sobre la asociación Reservation — Room

La multiplicidad 1..* se materializa en la base de datos mediante la tabla intermedia ReservationRoom, que guarda el precio por noche congelado en el momento de reservar. Es un detalle de implementación relacional y por eso no aparece como clase en el diagrama de dominio.