digraph ReservationSystemDiagram { graph [ rankdir=TB, splines=ortho, label="Lodge Reservation System", fontsize=20 ]; node [ shape=record, style=filled, fillcolor=lightyellow, fontname="Helvetica" ]; edge [ penwidth=1.0, fontname="Helvetica" ]; // Class Definitions AccomodationManager [label="{AccomodationManager|- accounts: AccountList\l|+ setDataStoreRoot(home: String): void\l+ loadAll(): void\l+ retrieveLoadedAccounts(): List\l+ retrieveAccount(acct_id: String): Account\l+ AddAccount(acct: Account): void\l+ UpdateAccount(acct: Account): void\l+ newAccount(...): Account\l+ addReservation(account: Account, reservation: Reservation): boolean\l+ findReservation(reservation_number: String): Reservation\l}"]; AccountList [label="{AccountList|# extends ArrayList\l+ add(account: Account): boolean\l+ save(acct: Account): void\l+ find(account_number: String): Account\l}"]; HotelReservation [label="{HotelReservation|+ ReservationType(): String\l+ calculatePrice(): float\l+ getPricePerNight(): float\l}"]; HouseReservation [label="{HouseReservation|+ ReservationType(): String\l+ calculatePrice(): float\l+ getPricePerNight(): float\l}"]; CabinReservation [label="{CabinReservation|+ ReservationType(): String\l+ calculatePrice(): float\l+ getPricePerNight(): float\l}"]; DataRepository [label="{DataRepository|- directoryPath: String\l- instance: DataRepository\l+ {static} setDataStoreRoot(path: String): void\l+ {static} getPath(): String\l+ {static} LoadAccount(file: Path): Account\l+ {static} WalkFileSystemTree(...): void\l}"]; // Data model classes (simplified) subgraph cluster_datamodel { label = "Data Models"; style = "dashed"; Address [label="{Address|- street: String\l- city: String\l- state: String\l- zip: String\l}"]; EmailAddress [label="{EmailAddress|- email: String\l}"]; Account [label="{Account|- account_number: String\l- phone_number: String\l- mailing_address: Address\l- email_address: EmailAddress\l- reservations: AccountReservationList\l|+ add(rsrv: Reservation): boolean\l+ Write(acct: Account): void\l+ findReservation(reservation_number: String): Reservation\l+ checkValid(): boolean\l}"]; AccountReservationList [label="{AccountReservationList|# extends ArrayList\l+ add(reservation: IReservation): boolean\l+ find(reservation_number: String): Reservation\l}"]; IReservation [label="{<>\nIReservation|+ getReservation_number(): String\l+ getAccountNumber(): String\l+ calculatePrice(): float\l+ checkValid(): boolean\l+ ReservationType(): String\l}"]; Reservation [label="{<>\nReservation|- reservation_number: String\l- physical_address: Address\l- reservation_start_date: ZonedDateTime\l- reservation_end_date: ZonedDateTime\l- reservation_status: ReservationStatusEnum\l- price: Float\l# accountNumber: String\l|+ Change(reservation: Reservation, newStatus: ReservationStatusEnum): void\l+ ReservationType(): String\l}"]; } // Relationships // Composition / Aggregation AccomodationManager -> AccountList [ arrowhead=odiamond, label="manages", taillabel="1", headlabel="1" ]; AccountList -> Account [ arrowhead=odiamond, label="contains", taillabel="1", headlabel="0..*" ]; Account -> AccountReservationList [ arrowhead=odiamond, label="has", taillabel="1", headlabel="1" ]; AccountReservationList -> IReservation [ arrowhead=odiamond, label="contains", taillabel="1", headlabel="0..*" ]; // Inheritance / Implementation Reservation -> IReservation [arrowhead=onormal, style=dashed, label="implements"]; HotelReservation -> Reservation [arrowhead=empty, label="extends"]; HouseReservation -> Reservation [arrowhead=empty, label="extends"]; CabinReservation -> Reservation [arrowhead=empty, label="extends"]; // Association / Dependency AccomodationManager -> DataRepository [arrowhead=vee, style=dashed, label="uses"]; Account -> Address [ arrowhead=vee, style=dashed, label="has a mailing address", taillabel="*", headlabel="1" ]; Account -> EmailAddress [ arrowhead=vee, style=dashed, label="has an email", taillabel="*", headlabel="1" ]; Reservation -> Address [arrowhead=vee, style=dashed, label="has physical & mailing addresses"]; }