{"id":1087,"date":"2023-09-10T10:42:31","date_gmt":"2023-09-10T08:42:31","guid":{"rendered":"https:\/\/oopm.org\/?page_id=1087"},"modified":"2025-03-18T22:14:20","modified_gmt":"2025-03-18T21:14:20","slug":"5-2-a-travel-booking-system-example","status":"publish","type":"page","link":"https:\/\/oopm.org\/?page_id=1087","title":{"rendered":"8.4 A travel booking system"},"content":{"rendered":"<div class=\"pdfprnt-buttons pdfprnt-buttons-page pdfprnt-top-right\"><a href=\"https:\/\/oopm.org\/index.php?rest_route=wpv2pages1087&print=pdf\" class=\"pdfprnt-button pdfprnt-button-pdf\" target=\"_blank\"><img decoding=\"async\" src=\"https:\/\/oopm.org\/wp-content\/plugins\/pdf-print\/images\/pdf.png\" alt=\"image_pdf\" title=\"View PDF\" \/><\/a><a href=\"https:\/\/oopm.org\/index.php?rest_route=wpv2pages1087&print=print\" class=\"pdfprnt-button pdfprnt-button-print\" target=\"_blank\"><img decoding=\"async\" src=\"https:\/\/oopm.org\/wp-content\/plugins\/pdf-print\/images\/print.png\" alt=\"image_print\" title=\"Print Content\" \/><\/a><\/div>\n<p class=\"wp-block-paragraph\">In the following we show another example using subclasses and virtual methods by making a model of elements of a travel agency that helps people making bookings.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There are many kinds of bookings; however in this example we cover a subset: travel bookings like flight bookings, and train bookings, bookings of hotel, and bookings of roundtrips. Some of them can be done via the internet, while others, like roundtrips, may require help from a travel agent.<\/p>\n\n\n\n<style>\n#XXXz {\n  width: 35%;\n  padding-left: 15px;\n  margin-left: 15px;\n  float: right;\n  background-color: lightgray;\n  font-size: 0.85rem;\n}\n<\/style>\n<p id=\"XXXz\">In the examples below, we use a number of auxiliary classes that are not specified, and as usual, this is indicated by <code>...<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The experience from the account example tells us that all these different types of booking have properties in common. This is modeled by a class <code>Booking<\/code> with all the common properties, like booking reference, reservation date, customer, handling agent and the last day of cancellation. The different types of bookings are then defined as subclasses of <code>Booking<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code has-custom-color-1-background-color has-background\"><code><strong>class<\/strong> Booking(bookingRef: <strong>var<\/strong> String): \n   reservationDate: <strong>var<\/strong> Date<mark style=\"background-color:rgba(0, 0, 0, 0);color:#a92828\" class=\"has-inline-color\">  <\/mark>\n   customer: <strong>ref<\/strong> Person\n   agent: <strong>ref<\/strong> Employee\n   lastCancelDate: <strong>var<\/strong> Date\n\n<strong>class<\/strong> Person: ...\n<strong>class<\/strong> Employee: ... <\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>bookingRef<\/code> is a string that uniquely identifies the booking. It is issued by e.g. the airline company and typically has to be used in order to cancel a booking.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Note that <code>reservationDate<\/code> represents the date at which the booking is made at the travel agency, not e.g. the departure date for a travel booking.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For all bookings there are three activities: register the booking in a booking register of the travel agency, confirm the booking, and cancel the booking.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Assuming that the travel agency keeps a register of bookings:<\/p>\n\n\n\n<pre class=\"wp-block-code has-custom-color-1-background-color has-background\"><code>bookingRegister: <strong>obj<\/strong> Set(Booking)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">the following action of <code>Booking<\/code> inserts the booking in this register:<\/p>\n\n\n\n<pre class=\"wp-block-code has-custom-color-1-background-color has-background\"><code><strong>class<\/strong> Booking:\n   -\"-\n&nbsp;&nbsp;&nbsp;bookingRegister.insert(this(Booking))<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Statements in a class description, as the method call above, are executed when a <code>Booking<\/code> object is generated.<\/p>\n\n\n\n<p class=\"has-small-font-size wp-block-paragraph\">Cancelling a booking is not the same for all types of bookings. This is reflected by defining the method <code>cancel<\/code> as a virtual method: :<\/p>\n\n\n\n<pre class=\"wp-block-code has-custom-color-1-background-color has-background\"><code><strong>class<\/strong> Booking:\n&nbsp;&nbsp; -\"-\n   cancel:&lt;\n      if (today &gt; lastCancelDate) :then\n         console.print(\"cancellation not possible\")\n      :else \n         bookingRegister.remove(this(Booking)) \n         inner(cancel) <mark style=\"background-color:rgba(0, 0, 0, 0);color:#493ab2\" class=\"has-inline-color\"> <\/mark><\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">However, there are some common things to be done for every type of cancellation, and that is specified in <code>cancel<\/code>, e.g. that cancellation is not possible after the last cancellation date, and that cancellation amounts to remove the booking from the  <code>bookingRegister<\/code>. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The special things to be done for the different types of bookings is represented by <code>inner(cancel)<\/code>, e.g. that the carriers or the hotel has to be informed that the booking has been cancelled.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The method <code>confirm<\/code> also depends on which type of booking to confirm, so that has to be defined specifically for each subclass of <code>Booking<\/code>. This is indicated by defining <code>confirm<\/code> as a virtual method. Even though it has to be defined specifically for each subclass of <code>Booking<\/code>, there are some common actions of <code>confirm<\/code>, and these are described as part of the virtual method:<\/p>\n\n\n\n<pre class=\"wp-block-code has-custom-color-1-background-color has-background\"><code><strong>class<\/strong> Booking:\n&nbsp;&nbsp; -\"-\n&nbsp;&nbsp; confirm -&gt; confirmText: <strong>var<\/strong> String:&lt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; confirmText:= \"Booking \" + bookingRef + \":\" '\\n'\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;inner(confirm)\n      confirmText := confirmText + \"has been confirmed\" + '\\n'   <\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>confirm<\/code> method computes a text that consist of the details of the <code>Booking<\/code>. This text is returned by confirm in the variable <code>confirmText<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Common to all bookings is that the confirmation text has the same text around the details of the actual booking. Execution of <code>inner<\/code> implies the execution the statements of the confirm of the given subclass, and this will add the detailed text of the <code>confirmText<\/code>. This implies that the special confirm methods in different subclasses are extensions of the actions of the virtual method confirm.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The travel agent may decide how to use the confirmation text: to print it for off-line checking, include it in a travel document, or send it by email to the customer.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A typical scenario in this example is that the travel agency is asked to find a travel from a city (origin) to another city (destination), be it by air or by train.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-custom-color-3-color\"> <\/mark><code>TravelBooking<\/code> object therefore has an <code>origin<\/code> and <code>destination<\/code> city:<\/p>\n\n\n\n<pre class=\"wp-block-code has-custom-color-1-background-color has-background\"><code><strong>class<\/strong> TravelBooking: Booking\n   origin, destination: <strong>ref<\/strong> City \n   departureDate: <strong>var<\/strong> Date   \n   confirm::&lt;\n      confirmText := confirmText +\n      \"from \" + origin.name + \"to \" + destination.name '\\n' <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-custom-color-3-color\">+\n   <\/mark>   \"at \" + departureDate\n      inner(confirm)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We do not go into details about <code>City<\/code>, we simply assume that it is represented by an<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-custom-color-3-color\"> <\/mark>instance of<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-custom-color-3-color\"> <\/mark>of class <code>City<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>class<\/strong> City: \n   name: <strong>var<\/strong> String\n   ...<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The agency handles two types of travel bookings, and these are represented by two subclasses of <code>TravelBooking<\/code>. In addition to <code>origin<\/code> and <code>destination<\/code>, these include the fact that cities may have more than one airport and often have more than one train station. At this point do not include details about flight or train routes with row and seat of the booking. We will later introduce a model of flight routes and flights.<\/p>\n\n\n\n<pre class=\"wp-block-code has-custom-color-1-background-color has-background\"><code><strong>class<\/strong> FlightBooking: TravelBooking\n   fromAirport, toAirport: <strong>ref<\/strong> Airport\n   theCarrier: <strong>ref<\/strong> Airline<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-custom-color-3-color\"> <\/mark>    \n   cancel::\n      theCarrier.notifyCancellation(bookingRef)\n   confirm::\n      confirmText := confirmText + \n         \"from \" + fromAirport.name + \"to \" + toAirport.name '\\n' \n\n<strong>class<\/strong> TrainBooking: TravelBooking\n   fromStation, toStation: <strong>ref<\/strong> TrainStation\n   theCarrier: <strong>ref<\/strong> TrainCompany\n   cancel::\n      theCarrier.notifyCancellation(bookingRef) \n   confirm::\n      confirmText := confirmText + \n         \"from \" + fromStation.name + \"to \" + toStation.name '\\n' <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-custom-color-3-color\"> <\/mark><\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">As above, this assumes the following classes:<\/p>\n\n\n\n<pre class=\"wp-block-code has-custom-color-1-background-color has-background\"><code><strong>class<\/strong> Airport: \n   name: <strong>var<\/strong> String\n   ...\n<strong>class<\/strong> TrainStation: \n   name: <strong>var<\/strong> String\n   ...<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">None of these classes, except <code>Flight<\/code>, are described in this book. Class <code>Flight<\/code> is defined in section <script>mkRef(\"Flight example\")<\/script>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Objects of class <code>HotelBooking<\/code> represent bookings of stays at a hotel. They have properties like <code>thehotel<\/code>: a reference to an object representing the hotel, <code>room<\/code>: the room number, <code>arrivalDate<\/code>, and <code>noOfNights<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code has-custom-color-1-background-color has-background\"><code><strong>class<\/strong> HotelBooking: Booking\n   theHotel: <strong>ref<\/strong> Hotel\n   arrivalDate: <strong>var<\/strong> Date\n   room: <strong>var<\/strong> Integer\n   noOfNights: <strong>var<\/strong> Integer\n   confirm::\n      confirmText := confirmText + \n         \"at \" + theHotel.name '\\n' +\n         \"from \" + arrivalDate  + noOfNights \" nights\" '\\n' <\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This assumes a class <code>Hotel<\/code> with at least a <code>name<\/code> attribute:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>class<\/strong> Hotel: \n   name: <strong>var<\/strong> String\n   addr: <strong>obj<\/strong> Addresss\n   ...<\/code><\/pre>\n\n\n\n<p class=\"has-background-background-color has-background wp-block-paragraph\">Class <code>Address<\/code> is not specified here, but a version of it is defined in section <script>mkRef(\"Addressable aspect\")<\/script>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The following diagram illustrates the hierarchy of <code>Booking<\/code> classes:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img fetchpriority=\"high\" decoding=\"async\" width=\"434\" height=\"341\" src=\"https:\/\/oopm.org\/wp-content\/uploads\/2024\/11\/BookingClassHierarchy.jpg\" alt=\"\" class=\"wp-image-9461\" style=\"width:331px;height:auto\" srcset=\"https:\/\/oopm.org\/wp-content\/uploads\/2024\/11\/BookingClassHierarchy.jpg 434w, https:\/\/oopm.org\/wp-content\/uploads\/2024\/11\/BookingClassHierarchy-300x236.jpg 300w\" sizes=\"(max-width: 434px) 100vw, 434px\" \/><figcaption class=\"wp-element-caption\">Booking Class Hierarchy<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The following is a sketch of the sequence of actions that has to be performed in order to make a <code>FlightBooking<\/code>, triggered somehow by an agent, given actual values of the following items:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>theCustomer: <strong>ref<\/strong> Person\norigin: <strong>ref<\/strong> City, \ndestination: <strong>ref<\/strong> City,\nfrom, to: <strong>ref<\/strong> Airport,\ndepartureDate: <strong>var<\/strong> Date<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Finding a carrier that has flights from origin to destination cities is done by invoking a method <code>findAirlineCarrier<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>airlineCarrier: <strong>ref<\/strong> Airline\n\nairlineCarrier := findAirlineCarrier(origin, destination)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We do not provide the details of <code>findAirlineCarrier<\/code><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-custom-color-3-color\">:<\/mark><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>findAirlineCarrier(origin, destination: <strong>ref<\/strong> City) -&gt; carrier: <strong>ref<\/strong> Airline:\n   ...<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Next a flight is booked by invoking <code>bookFlight<\/code> of <code>airlineCarrier<\/code>, providing a booking reference:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>bookingRef: <strong>var<\/strong> String\n\nbookingRef := airlineCarrier.bookFlight(from, to, departureDate)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The method <code>bookFlight<\/code> has this signature:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>bookFlight(from, to: <strong>ref<\/strong> Airport, departureDate: <strong>var<\/strong> Date)-&gt; bookingRef: <strong>var<\/strong> String:\n   ... <\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Given the value of  <code>bookingRef<\/code> it is now possible to generate a <code>FlightBooking<\/code> object:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>booking: <strong>ref<\/strong> FlightBooking\n\nbooking := FlightBooking(bookingRef) \nbooking.customer := theCustomer\nbooking.carrier := theCarrier\nbooking.origin := origin\n...  \nbooking.registerBooking \nbooking.confirm\ntheCustomer.sendEmail(booking.confirmText)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To complete the example, we need to represent waggon and seat number for train reservation and row and seat number for flight reservations. We return to this in section <script>mkRef(\"Self-constrained\u00a0virtual class\")<\/script>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Bookings of round trips is where the travel agents really come into play. A round trip is not a special type of booking, but rather consist of a list of bookings. A roundtrip is based on an itinerary that either is presented by the customer as the desired\/planned journey, or is worked out in a cooperation between the customer and a travel agent. As a round trip in this example includes both travel bookings and hotel bookings, a round trip is represented by an object of the class <code>RoundTrip<\/code>. The trip is an ordered list of bookings, i.e. not just a set, as there is a sequence of travels and hotel stays.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>class<\/strong> RoundTripBooking:<br>   plan: <strong>ref<\/strong> Itinerary  <br>   trip: <strong>obj<\/strong> OrderedList(Booking)<br>   confirm:<br>      trip.scan<br>         b.confirm  <br><strong>class<\/strong> Itinenary: <br>   ...<\/code><\/pre>\n<div style=\"display:flex; gap:10px;justify-content:center\" class=\"wps-pgfw-pdf-generate-icon__wrapper-frontend\">\n\t\t<a  href=\"https:\/\/oopm.org?action=genpdf&amp;id=1087\" class=\"pgfw-single-pdf-download-button\" ><img src=\"https:\/\/oopm.org\/wp-content\/plugins\/pdf-generator-for-wp\/admin\/src\/images\/PDF_Tray.svg\" title=\"Generate PDF\" style=\"width:auto; height:45px;\"><\/a>\n\t\t<\/div>","protected":false},"excerpt":{"rendered":"<p>In the following we show another example using subclasses and virtual methods by making a model of elements of a travel agency that helps people making bookings. There are many kinds of bookings; however in this example we cover a subset: travel bookings like flight bookings, and train bookings, bookings of hotel, and bookings of [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":1008,"menu_order":4,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1087","page","type-page","status-publish","hentry"],"mb":[],"mfb_rest_fields":["title","gutenberg_elementor_mode"],"_links":{"self":[{"href":"https:\/\/oopm.org\/index.php?rest_route=\/wp\/v2\/pages\/1087","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/oopm.org\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/oopm.org\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/oopm.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/oopm.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1087"}],"version-history":[{"count":158,"href":"https:\/\/oopm.org\/index.php?rest_route=\/wp\/v2\/pages\/1087\/revisions"}],"predecessor-version":[{"id":11370,"href":"https:\/\/oopm.org\/index.php?rest_route=\/wp\/v2\/pages\/1087\/revisions\/11370"}],"up":[{"embeddable":true,"href":"https:\/\/oopm.org\/index.php?rest_route=\/wp\/v2\/pages\/1008"}],"wp:attachment":[{"href":"https:\/\/oopm.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1087"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}