Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

UML Components Case Study

Download as pdf or txt
Download as pdf or txt
You are on page 1of 29

UML Components

(c) Addison Wesley 2000 1


UML Components
(c) Addison Wesley 2000
Appendix A
Case Study Details
Business Process
UML Components
(c) Addison Wesley 2000 2
Check
availability
Make
reservation
Take up
reservation
Cancel
reservation
Amend
reservation
Reservation
maker
System
[suitable
room]
[else]
Guest
customer arrives/
cancel request/
amendment
request/
Wait for
event
enquiry/
Process no
show
no show/
Confirm
reservation
Notify billing
system
Use cases
UML Components
(c) Addison Wesley 2000 3
Reservation system
ReservationMaker
Guest
BillingSystem
ReservationAdministrator
Cancel a
reservation
Make a
reservation
Update a
reservation
Take up a
reservation
Process no
shows
Add, amend,
remove...
Identify
reservation
<<include>>
<<include>>
<<include>>
Name Make a reservation
Initiator Reservation Maker
Goal Reserve room(s) at a hotel
Main success scenario
1. Reservation Maker asks to make a reservation
2. Reservation Maker selects in any order hotel, dates and room type
3. System provides price to Reservation Maker
4. Reservation Maker asks for reservation
5. Reservation Maker provides name and postcode (zip code)
6. Reservation Maker provides contact email address
7. System makes reservation and allocates tag to reservation
8. System reveals tag to Reservation Maker
9. System creates and sends confirmation by email
Extensions
3. Room not available
a) System offers alternatives
b) Reservation Maker selects from alternatives
3b) Reservation Maker rejects alternatives
a) Fail
4. Reservation Maker declines offer
a) Fail
6. Customer already on file (based on name and postcode)
a) Resume 7
UML Components
(c) Addison Wesley 2000 4
Name Take up reservation
Initiator Guest
Goal Claim a reservation and check in to the hotel
Main success scenario
1. Guest arrives at hotel and claims a reservation
2. Include Identify Reservation
3. Guest confirms details of stay duration, room type
4. System allocates room
5. System notifies billing system that a stay is starting
Extensions
3. Reservation not identified
a) Fail
Name Identify reservation
Initiator included only
Goal Identify an existing reservation
Main success scenario
1. Actor provides reservation tag
2. System locates reservation
Extensions
2. System cannot find a reservation with the given tag
a) Actor provides name and post code
b) System displays active reservations for that customer
c) Actor selects the reservation
d) Stop
2. The reservation tag refers to a reservation at a different hotel
a2) Fail
2b) No active reservations at this hotel for this customer
a) Fail
UML Components
(c) Addison Wesley 2000 5
Business Concept Model
Hotel Chain
Hotel
Clerk
Room
Bill
Payment
Reservation Customer
Address
1
1..*
1
1..*
1..*
1
1
*
* 0..1
0..1
0..1
1
1
* 1
1
0..1
*
*
allocation
contactedHotel
contactAddress
RoomType
1
*
1
*
UML Components
(c) Addison Wesley 2000 6
Business Type Diagram
<<type>>
RoomType
name: String
price(Date): Currency
stayPrice(DateRange): Currency
available(DateRange): Boolean
<<core>>
Customer
name: String
postCode: String
email: String
1
<<core>>
Hotel
name: String
<<type>>
Room
number: String
<<type>>
Reservation
resRef: String
dates: DateRange
1..*
1
1
*
*
0..1
*
allocation
1
*
1
1..*
1
*
{Hotel::room.roomType =
Hotel::roomType}
{Reservation::hotel =
Reservation::roomType.hotel}
UML Components
(c) Addison Wesley 2000 7
context RoomType
-- AVAILABILITY RULES
-- a room is available if the number of rooms reserved on all dates
-- in the range is less than the number of rooms
available(dr) = dr.asSet->collect(d | reservation->select(r | r.allocation->isEmpty and
r.dates.includes(d))->size)->max < room->size)
-- can never have more reservations for a date than rooms (no overbooking)
Date->forAll(d | reservation->select( r | not r.allocation->isEmpty and
r.dates.includes(d))->size) <= room->size
-- PRICING RULES
-- the price of a room for a stay is the sum of the prices for the days in the stay
stayPrice(dr) = dr.asSet->collect(d | price(d))->sum
Structured Data Types
(BTM)
UML Components
(c) Addison Wesley 2000 8
<<data type>>
DateRange
start: Date
end: Date
asSet: Date [ ]
includes(d: Date): Boolean
{dr.includes(d) = d >= dr.start an d <= dr.end}
{dr.asSet = Date->select(aDate | dr.includes(aDate)}
<<data type>>
Currency
Interface Responsibility Diagram
UML Components
(c) Addison Wesley 2000 9
<<type>>
RoomType
name: String
price(Date): Currency
stayPrice(DateRange): Currency
available(DateRange): Boolean
<<core>>
Customer
name: String
postCode: String
email: String
1
<<interface type>>
IHotelMgt
<<interface type>>
ICustomerMgt
*
*
<<core>>
Hotel
name: String
<<type>>
Room
number: String
<<type>>
Reservation
resRef: String
dates: DateRange
1..*
*
*
0..1
*
allocation
1
*
1..*
1
*
Structured Data Types
(Interface specs)
UML Components
(c) Addison Wesley 2000 10
<<data type>>
ReservationDetails
hotel: HotelId
dates: DateRange
roomType: String
<<data type>>
HotelDetails
id: HotelId
name: String
roomTypes: String [ ]
<<data type>>
CustomerDetails
name: String
postCode[0..1]: String
email[0..1]: String
<<data type>>
CustId
<<data type>>
DateRange
start: Date
end: Date
asSet: Date [ ]
includes(d: Date): Boolean
{dr.includes(d) = d >= dr.start an d <= dr.end}
{dr.asSet = Date->select(aDate | dr.includes(aDate)}
<<data type>>
Currency
<<data type>>
HotelId
System interfaces
UML Components
(c) Addison Wesley 2000 11
Hotel
id: HotelId
name: String
<<interface type>>
IMakeReservation
getHotelDetails (in match: String): HotelDetails [ ]
getRoomInfo (in res: ReservationDetails, out availability: Boolean, out price: Currency)
makeReservation (in res: ReservationDetails, in cus: CustomerDetails, out resRef: String): Integer
Room
RoomType
name: String
available(during: DateRange): Boolean
Customer
name: String
postCode: String
email: String
Reservation
resRef: String
dates: DateRange
claimed: Boolean
*
1..*
1
1
1
1
0..1
* * *
* *
1
allocation
IMakeReservation::RoomType
-- room types are not shared across hotels
room.hotel->size=1
-- a room is available if the number of rooms reserved on all dates
-- in the range is less than the number of rooms
available(dr) = dr.asSet->collect(d | reservation->select(r | not r.claimed and
r.dates.includes(d))->size)->max < room->size
-- can never have more reservations for a date than rooms
Date->forAll(d | reservation->select( r | not r.claimed and
r.dates.includes(d))->size) <= room->size
IMakeReservation::Reservation
-- a reservation is claimed if it has a room allocated to it
claimed = allocation->notEmpty
-- the roomtype must be a room type of the hotel
hotel = roomType.room.hotel
UML Components
(c) Addison Wesley 2000 12
getHotelDetails (in match: String): HotelDetails [ ]
pre:
true
post:
-- the result will only include hotels that are in the info model of this interface
result->forAll(hd | hotel->exists(h | h.name = hd.name and
h.id = hd.id and
h.room.roomType.name = hd.roomTypes)
-- nb: matching algorithm not specified here
IMakeReservation
getRoomInfo (in res: ReservationDetails, out availability: Boolean, out price: Currency)
pre:
-- the hotel and room type specified are valid
hotel.id->includes(res.hotel) and
hotel.room.roomType.name->includes(res.roomType)
post:
Let rt = hotel.room.roomType->select(x | x.room.hotel.id = res.hotel and
x.name = res.roomType)->asSequence->first in
(availability = rt.available(res.dateRange))
-- nb: price policy not specified here
IMakeReservation
UML Components
(c) Addison Wesley 2000 13
makeReservation (in res: ReservationDetails, in cus: CustomerDetails, out resRef: String): Integer
pre:
-- the hotel and room type specified are valid
hotel.id->includes(res.hotel) and
hotel.room.roomType.name->includes(res.roomType)
post:
result=0 implies
-- a reservation was created
-- note invariant on roomType governing max no of reservations
Let h = hotel->select(x | x.id = res.hotel)->asSequence->first in
(h.reservation - h.reservation@pre)->size = 1 and
Let r = (h.reservation - h.reservation@pre)->asSequence->first in
r.resRef = resRef and r.dates = res.dateRange and
r.roomType.name = res.roomType and not r.claimed and
r.customer.name = cus.name and
cus.postCode->notEmpty implies cus.postCode = r.customer.postCode and
cus.email->notEmpty implies cus.email = r.customer.email
-- result=1 implies customer not found and unable to create
-- result=2 implies more than one matching customer
IMakeReservation
Hotel
id: HotelId
<<interface type>>
ITakeUpReservation
getReservation (in resRef: String, out rd: ReservationDetails, out cus: CustomerDetails): Boolean
beginStay (in resRef: String, out roomNumber: String): Boolean
Room
number: String
RoomType
name: String
Customer
name: String
postCode: String
email: String
Reservation
resRef: String
dates: DateRange
claimed: Boolean
1..*
1
1
1
1
0..1
* * *
* *
1
allocation
*
UML Components
(c) Addison Wesley 2000 14
ITakeUpReservation::RoomType
-- room types are not shared across hotels
room.hotel->size=1
ITakeUpReservation::Reservation
-- a reservation is claimed if it has a room allocated to it
claimed = allocation->notEmpty
-- the roomtype must be a room type of the hotel
hotel = roomType.room.hotel
getReservation (in resRef: String, out rd: ReservationDetails, out cus: CustomerDetails): Boolean
pre:
post:
result implies
-- there is a reservation with this number
reservation->exists (r | r.resRef = resRef) and
Let res = reservation->select (r | r.resRef = resRef)->asSequence->first in
-- and it hasnt been claimed already
not res.claimed and
-- and the returned details match that one
rd.hotel = res.hotel.id and
rd.dateRange = res.dates and
rd.roomType = res.roomType.name and
cus.name = res.customer.name and
cus.postCode = res.customer.postCode and
cus.email = res.customer.email
ITakeUpReservation
UML Components
(c) Addison Wesley 2000 15
beginStay (in resRef: String, out roomNumber: String): Boolean
pre:
-- resRef is valid
reservation->exists (r | r.resRef = resRef) and
-- not already claimed
not reservation->exists (r | r.resRef = resRef and r.claimed)
post:
Let res = reservation->select (r | r.resRef = resRef)->asSequence->first in
result implies
-- the reservation is now claimed
res.claimed and
roomNumber = res.allocation.number
-- nb room allocation policy not defined here
ITakeUpReservation
<<interface type>>
IBilling
openAccount (in res: ReservationDetails, in cus: CustomerDetails)
UML Components
(c) Addison Wesley 2000 16
Business type interfaces
<<interface type>>
IHotelMgt
getHotelDetails (in match: String): HotelDetails [ ]
getRoomInfo (in res: ReservationDetails, out availability: Boolean, out price: Currency)
makeReservation (in res: ReservationDetails, in cus: CustId, out resRef: String): Boolean
getReservation(in resRef: String, out rd ReservationDetails, out cusId: CustId): Boolean
beginStay (resRef: String , out roomNumber: String): Boolean
Hotel
id: HotelId
name: String
Room
number: String
RoomType
name: String
available(during: DateRange): Boolean
price(on: Date): Currency
stayPrice(for: DateRange): Currency
Customer
id: CustId
Reservation
resRef: String
dates: DateRange
claimed: Boolean
*
1..*
1
1
1
1
0..1
* * *
* *
1
allocation
*
UML Components
(c) Addison Wesley 2000 17
IHotelMgt::RoomType
-- room types are not shared across hotels
room.hotel->size=1
-- a room is available if the number of rooms reserved on all dates
-- in the range is less than the number of rooms
available(dr) = dr.asSet->collect(d | reservation->select(r | not r.claimed and
r.dates.includes(d))->size)->max < room->size
-- can never have more reservations for a date than rooms
Date->forAll(d | reservation->select( r | not r.claimed and
r.dates.includes(d))->size) <= room->size
-- the price of a room for a stay is the sum of the prices for the days in the stay
stayPrice(dr) = dr.asSet->collect(d | price(d))->sum
IHotelMgt::Reservation
-- a reservation is claimed if it has a room allocated to it
claimed = allocation->notEmpty
-- the roomtype must be a room type of the hotel
hotel = roomType.room.hotel
getHotelDetails (in match: String): HotelDetails [ ]
pre:
true
post:
-- the result will only include hotels whose name matches
result->collect (hd | hd.id) =
hotel->select(h | h.name.substring(1, match.size) = match)->collect (h | h.id) and
result->forAll(hd | hotel->exists(h | h.name = hd.name and
h.id = hd.id and
h.room.roomType.name = hd.roomTypes)
IHotelMgt
UML Components
(c) Addison Wesley 2000 18
IHotelMgt
getRoomInfo (in res: ReservationDetails, out availability: Boolean, out price: Currency)
pre:
-- the hotel id and room type are valid
hotel->exists(h | h.id = res.hotel and h.room.roomType.name->includes(res.roomType))
post:
-- locate the requested RoomType of the requested Hotel
Let rt = hotel.room.roomType->select(x | x.room.hotel.id = res.hotel and
x.name = res.roomType)->asSequence->first in
-- return values reflect RoomType status
(availability = rt.available(res.dateRange)) and
(price = rt.stayPrice(res.dateRange))
IHotelMgt
makeReservation (in res: ReservationDetails, in cus: CustId, out resRef: String): Boolean
pre:
-- the hotel id and room type are valid
hotel->exists(h | h.id = res.hotel and h.room.roomType.name->includes(res.roomType))
post:
result implies
-- a reservation was created
-- note invariant on roomType governing max no of reservations
-- identify the hotel
Let h = hotel->select(x | x.id = res.hotel)->asSequence->first in
-- only one more reservation now than before
(h.reservation - h.reservation@pre)->size = 1 and
-- identify the reservation
Let r = (h.reservation - h.reservation@pre)->asSequence->first in
-- return number is number of the new reservation
r.resRef = resRef and
-- other attributes match
r.dates = res.dateRange and
r.roomType.name = res.roomType and not r.claimed and
r.customer.id = cus
UML Components
(c) Addison Wesley 2000 19
IHotelMgt
getReservation(in resRef: String, out rd ReservationDetails, out cus: CustId): Boolean
pre:
true
post:
result implies
-- there is a reservation with this number
reservation->exists (r | r.resRef = resRef) and
Let res = reservation->select (r | r.resRef = resRef)->asSequence->first in
-- and it hasnt been claimed already
not res.claimed and
-- and the returned details match that one
rd.hotel = res.hotel.id and
rd.dateRange = res.dates and
rd.roomType = res.roomType.name and
cus = res.customer.id
IHotelMgt
beginStay (in resRef: String, out roomNumber: String): Boolean
pre:
-- resRef is valid
reservation->exists (r | r.resRef = resRef) and
-- not already claimed
not reservation->exists (r | r.resRef = resRef and r.claimed)
post:
Let res = reservation->select (r | r.resRef = resRef)->asSequence->first in
result implies
-- the reservation is now claimed
res.claimed and
roomNumber = res.allocation.number
-- nb room allocation policy not defined
UML Components
(c) Addison Wesley 2000 20
<<interface type>>
ICustomerMgt
getCustomerMatching (in custD: CustomerDetails, out cusId: CustId): Integer
createCustomer(in custD: CustomerDetails, out cusId: CustId): Boolean
getCustomerDetails (in cus: CustId): CustomerDetails
notifyCustomer (in cus: CustId, in msg: String)
Customer
id: CustId
name: String
postCode: String
email: String
*
ICustomerMgt
getCustomerMatching (in custD: CustomerDetails, out cusId: CustId): Integer
pre:
true
post:
-- determine the number of matching customers
Let cSet = customer->select(c | c.name = custD.name and (if custD.postCode->notEmpty
then c.postCode = custD.postCode else true endif)) in
(result=0 implies
-- only one customer matches info supplied: the id returned will be that one!
cSet->size = 1 and cusId = cSet->asSequence->first.id) and
(result=1 implies
-- no customer found
cSet->isEmpty) and
(result=2 implies
-- more than one match
cSet->size > 1)
UML Components
(c) Addison Wesley 2000 21
ICustomerMgt
createCustomer (in custD: CustomerDetails, out cusId: CustId): Boolean
pre:
custD.postCode->notEmpty and
custD.email->notEmpty
post:
result implies
-- new customer (with name not previously known) created
not customer@pre->exists(c | c.name = custD.name) and
(customer - customer@pre)->size = 1 and
Let c = (customer - customer@pre)->asSequence->first in
c.name = custD.name and
c.postCode = custD.postCode and
c.email = custD.email and
c.id = cusId
ICustomerMgt
getCustomerDetails (in cus: CustId): CustomerDetails
pre:
-- cus is valid
customer->exists(c | c.id = cus)
post:
Let theCust = customer->select(c | c.id = cus)->asSequence->first in
result.name = theCust.name
result.postCode = theCust.postCode
result.email = theCust.email
UML Components
(c) Addison Wesley 2000 22
ICustomerMgt
notifyCustomer (in cus: CustId, in msg: String)
pre:
-- cus is valid
customer->exists(c | c.id = cus)
post:
-- cus has been notified by email using msg
Component Architecture
UML Components
(c) Addison Wesley 2000 23
<<comp spec>>
HotelMgr
IHotelMgt
<<comp spec>>
CustomerMgr
ICustomerMgt
<<comp spec>>
BillingSystem
IBilling
<<comp spec>>
Reservation
System
IMakeReservation
ITakeUpReservation
Component Specs
UML Components
(c) Addison Wesley 2000 24
ReservationSystem
<<comp spec>>
Reservation
System
IMakeReservation
IHotelMgt ICustomerMgt
ITakeUpReservation
IBilling
ReservationSystem
<<comp spec>>
Reservation
System
<<interface type>>
ICustomerMgt
<<interface type>>
IHotelMgt
1 {frozen}
<<interface type>>
IBilling 1 {frozen}
1 {frozen}
UML Components
(c) Addison Wesley 2000 25
Constraints
-- between offered interfaces
IMakeReservation::hotel corresponds to ITakeUpReservation::hotel
IMakeReservation::reservation corresponds to ITakeUpReservation:: reservation
IMakeReservation::customer corresponds to ITakeUpReservation::customer
-- between offered interfaces and used interfaces
IMakeReservation::hotel corresponds to iHotelMgt.hotel
IMakeReservation::reservation corresponds to iHotelMgt.reservation
IMakeReservation::customer corresponds to iCustomerMgt.customer
ReservationSystem
/IMakeReservation:ReservationSystem
1:getHotelDetails(s)
/IHotelMgt
1.1:getHotelDetails(s)
/IMakeReservation:ReservationSystem
1:getRoomInfo (r, a, p)
/IHotelMgt
1.1:getRoomInfo(r, a, p)
ReservationSystem
UML Components
(c) Addison Wesley 2000 26
/IMakeReservation:ReservationSystem
1:makeReservation (r, c, rr)
/IHotelMgt
1.2:makeReservation(r,id,rr)
/ICustomerMgt
1.1:getCustomerMatching(c, id) {result=0}
1.3:notifyCustomer(id, s)
ReservationSystem
{where s includes rr etc}
/IMakeReservation:ReservationSystem
1:makeReservation (r, c, rr)
/IHotelMgt
1.3:makeReservation(r,id,rr)
/ICustomerMgt
1.1:getCustomerMatching(c, id) {result=1}
1.2:createCustomer(c, id)
1.4:notifyCustomer(id, s)
ReservationSystem
{where s includes rr etc}
UML Components
(c) Addison Wesley 2000 27
1:getReservation(rr, rd. cd)
/ITakeUpReservation:ReservationSystem
/IHotelMgt
1.1:getReservation(rr, rd, c)
ReservationSystem
/ICustomerMgt
1.2:getCustomerDetails(c): cd
/ITakeUpReservation:ReservationSystem
/IHotelMgt
1.1:getReservation(rr, rd, c)
1.2:beginStay(rr, n)
1:beginStay(rr, n)
/IBilling
1.4:openAccount(rd, cd)
ReservationSystem
/ICustomerMgt
1.3:getCustomerDetails(c): cd
UML Components
(c) Addison Wesley 2000 28
BillingSystem
<<comp spec>>
BillingSystem
IBilling
CustomerMgr
<<comp spec>>
CustomerMgr
ICustomerMgt
UML Components
(c) Addison Wesley 2000 29
HotelMgr
<<comp spec>>
HotelMgr
IHotelMgt

You might also like