Starting from:

$30

CS20006- Assignment 3: Inheritance Hierarchy, Design, Analysis & Testing Solved

We need to develop a rudimentary railway reservation / booking system (somewhat like IRCTC Train Ticket Booking, but extremely scaled down in features). We present various stages of this development process leading finally to the specific tasks of the assignment.

1       Specification
This is the outline specification that has been acquired from the client.

1.1      Requirement Statement
The entities involved in the booking system design include:

•   Station: Every Station is identified by its name. Booking is done between any two Stations.

•   Railways: It is the Indian railways. It has a collection of Stations with pairwise distance between Stations known a priori. Naturally, there can be only one Railways, called IndianRailways, in the system.

•   Date: Any valid date in dd/MMM/yy format.

•   BookingClass: There are several BookingClasses for travel (as in Indian Railways fare classes explained). Each BookingClass has the following attributes:

–    Name: Name of the BookingClass

–    Fare Load Factor: The factor by which the fare for travel by this BookingClass would be loaded over the base fare. This may change from time to time.

–    Seat / Berth: Whether the BookingClass provides sleeping berths or just seats. This will not change in future.

–    AC / Non-AC: Whether BookingClass is air-conditioned or otherwise. This will not change in future. – # of Tiers: How many tiers exist in the coach for this BookingClass. This will not change in future.

–    Luxury / Ordinary: Whether this BookingClass is considered luxurious by the Government. This may change from time to time.

New booking classes may be added in future.

•   Booking: A Booking is requested with the following information:

–    fromStation: Station from which the travel starts for the Booking. This is given by the name of the Station

–    toStation: Station at which the travel ends for the Booking. This is given by the name of the Station

–    date: Date of travel for the Booking

–    bookingClass: BookingClass for the Booking

–    passenger: Details of the passenger including name, aadhaar number, date of birth, gender, mobile number, and category of the passenger. This is for future extension and optional for now.

On request of a Booking, the same is processed and fare is computed based on the business logic given in Section 1.3. The Booking is then confirmed with PNR and other details on the output. PNR is serially allocated starting with 1.

•   Passenger: A Passenger may have the following details:

–    name: Name of the passenger

–    aadhaar #: Aadhaar Number to be used as a unique ID

–    dateOfBirth: Date of birth to be used for verification of age

–    gender: Gender of the passenger: male or female

–    mobile #: Mobile number (optional)

–    category: One of General, Ladies, Senior Citizen, Divyaang, Tatkal, Premium Tatkal

1.2      Assumptions
The following assumptions are made for the design:

•   IndianRailways has a given set of Stations with distances known a priori. The list of Stations and distances between them are given as Master Data in Section 1.4. No new station can be added to the IndianRailways and distance between pair of stations do not change.

•   A Booking, as requested, is always available - between any pair of Stations, on any Date, and for any BookingClass

•   No passenger information is considered for the Booking

1.3      Business Logic
The fare between a pair of stations for a booking class is determined through the following steps:

•   Base Fare Rate: The base fare for every KM of travel = Rs. 0.5. This may change from time to time.

•   Base Fare: The base fare between two stations is computed by multiplying the distance between the stations with the base fare for every KM of travel. The base fare applies to the Sleeper booking class.

•   Loaded Fare: For booking classes other the Sleeper, the fare is loaded by a factor with respect to the Sleeper booking class fare as shown in the Booking Class Matrix (Section 1.4.2). The load factor may change from time to time.

•   AC Surcharge: Further, for air-conditioned classes, AC surcharge of Rs. 50 will be charged on the loaded fare. This may change from time to time.

•   Luxury Tax: Finally, there is a 25% luxury tax to be imposed for all luxury class bookings on the fare computed with surcharge. This may change from time to time. The luxury classification as well as taxation rate may change from time to time.

•   Final fare is rounded to the nearest integer.

•   Date has no effect on the fare.

•   Passenger has no effect on the fare as it is being ignored for now.

1.3.1       Example
For a booking from Delhi to Mumbai:

By AC3Tier:

•   Distance from Delhi to Mumbai = 1447km

•   Base fare = 1447km * Rs. 0.5 / km =

•   Loaded fare for AC3Tier = Rs. 723.50 * 1.75 = Rs. 1266.125

•   After adding the AC surcharge, we get Rs. 1266.125 + Rs. 50 = Rs. 1316.125 = Rs. 1316/= (rounded)

By ACFirstClass:

•   Distance from Delhi to Mumbai = 1447km

•   Base fare = 1447km * Rs. 0.5 / km =

•   Loaded fare for ACFirstClass = Rs. 723.50 * 3.0 = Rs. 2170.50

•   After adding the AC surcharge, we get Rs. 2170.50 + Rs. 50 = Rs. 2220.50

•   Finally, we levy the luxury tax to get Rs. 2220.50 * 1.25 = Rs. 2775.625 = Rs. 2776/= (rounded)

1.4      Master Data
1.4.1       Stations
IndianRailways has five stations, namely: Mumbai, Delhi, Bangalore, Kolkata, and Chennai. The distances between the stations are given below:

Station Distance Matrix

From

Station
 
 
To Station
 
Mumbai
Delhi
Bangalore
Kolkata
Chennai
 
 
Distance in KM
 
Mumbai
X
1447
 
 
 
Mumbai
 
 
981
 
 
Mumbai
 
 
 
2014
 
Mumbai
 
 
 
 
1338
Delhi
 
X
2150
 
 
Delhi
 
 
 
1472
 
Delhi
 
 
 
 
2180
Bangalore
 
 
X
1871
 
Bangalore
 
 
 
 
350
Kolkata
 
 
 
X
1659
Distance between a pair of stations is symmetric

1.4.2        Booking Classes
IndianRailways has seven booking classes as follows - shown with their respective attributes:

Booking Class Matrix

Booking Class
Name
Fare
Seat /
AC
#
Luxury /
Remarks
 
 
Load
Berth
 
of
Ordinary
 
 
 
Factor
 
 
Tiers
 
 
ACFirstClass
AC
3.00
Berth
Yes
2
Luxury
AC 2 berth
(1A)
First Class
 
 
 
 
 
coupe
AC2Tier
AC
2.00
Berth
Yes
2
Ordinary
AC 2 berth inside,
(2A)
2 Tier
 
 
 
 
 
2 berth on side
FirstClass
First
2.00
Berth
No
2
Luxury
Non-AC 2 berth
(FC)
Class
 
 
 
 
 
coupe
AC3Tier
AC
1.75
Berth
Yes
3
Ordinary
AC 3 berth inside,
(3A)
3 Tier
 
 
 
 
 
2 berth on side
ACChairCar
AC
1.25
Seat
Yes
0
Ordinary
AC chairs
(CC)
Chair Car
 
 
 
 
 
 
Sleeper
Sleeper
1.00
Berth
No
3
Ordinary
Non-AC 3 berth inside,
(SL)
 
 
 
 
 
 
2 berth on side
SecondSitting
Second
0.50
Seat
No
0
Ordinary
Bench seating
(2S)
Sitting
 
 
 
 
 
 
•   New booking classes may be added in future

•   Fare load factors may change from time to time

•   Luxury / Ordinary categorization may change according to tax rules

•   Seat / Berth & AC / non-AC classification, and # of tiers will not change in future

2        Analysis of Specification
We first analyze the specifications to identify the classes and hierarchy for the design. We also try to extract possible constraints on the design.

•   Station and Date are simple data classes.

•   Class Railways should be a singleton and should contain the master data of stations and distances. The singleton should be constant as no station can be added and distances cannot be changed.

•   Different Booking Classes should be a polymorphic hierarchy rooted at BookingClasses which may be an abstract base class. Instead of making it a flat hierarchy, it would be good to make it a multi-level hierarchy. This would need identification of abstract base sub-classes that are aligned with one or more properties of the Booking Classes.

If multiple properties are used in organizing the hierarchy, then the model would need multiple inheritance. However, we do not want to use multiple inheritance for the associated complications and inefficiency. Rather, we would use single inheritance on the strongest property and use the rest as HAS-A with polymorphic value based on the leaf class.

Naturally, there can be two candidates for this as Fare Load Factor, # of Tiers, and Luxury / Ordinary are more like pure attributes and clearly not useful for hierarchy:

–    AC or Non-AC: Air-condition leads to comfort level, and is not fundamental to travel. So this is a weak candidate.

–    Seat or Berth: This is fundamental property for a rail travel. So this is a strong candidate.

So we may introduce several intermediate abstract base classes on the strong property and its closest associated attribute, viz. the number of tiers.

Further we may note that every concrete booking class has all fixed properties and there should be no need to construct more than one object for any of them. So there may be a singleton constant object for each which, kind of, will stand for its polymorphic type.

The hierarchy should be extensible in future as new booking classes are added.

•   Booking may be treated as a simple concrete class with the parameters mentioned in the specification. We may keep Passenger as a null-able default for future extension.

Booking may be also be modeled as a polymorphic base class as with the introduction of Passenger in future it is likely to lead to a booking hierarchy.

•   Class Passenger may be an empty abstract base class. Since we are not going to use it, we would not need to make objects for the same. However, it would be good to have it as a polymorphic base for future extension, especially since the specification talks of various categories of passengers.

3        High Level Design
Based on the analysis, now we carry out the High Level Design (HLD) below for Classes, Interfaces, Constants, Statics, Exceptions, and overall design considerations.

3.1      Design Principles
The following design principles may be adhered to in the HLD:

•   Flexible & Extensible Design

–    The design should be flexible. That is, it should be easy to change the changeable parameters (like base rate, load factor etc.) easily from the Application space. This should should not need re-building of the library of classes.

–    The design should be extensible. That is, it should be easy to add new behaviour (classes) wherever indicated in the specification (like Booking Classes, Booking, Passenger, etc.). This should not require a re-coding of the existing applications.

•   Minimal Design

–    Only the stated models and behaviour should be coded. No extra class or method should be coded.

–    Less code, less error principle to be followed.

•   Reliable Design

–    Reliability should be a priority. Everything should work as designed and coded.

–    Data members, methods and objects should be made constant wherever possible.

–    Parameters should be appropriately defaulted wherever possible

•   Testable Design

–    Every class should support the output streaming operator for checking intermittent output if needed.

–    Every class should be tested with an appropriate test application for its unit functionality (Section 6.1).

–    Test Applications (Section 6.2) and regression test suites should be designed for testing the application on (at least) the common scenarios of use.

3.2     Classes
•   Class Station HAS-A name.

•   Class Railways is a singleton called IndianRailways. It has a collection of the Stations and their mutual distances. IndianRailways is a constant object.

•   Class Date is discussed in the lecture modules.

•   Class BookingClasses HAS-A loadFactor. Remaining attributes may be encoded on the methods in the hierarchy classes.

•   Class Booking HAS-A fromStation, toStation date, and bookingClass from the booking request where every station name, date and booking class are assumed to have been given correctly. Further it HAS-A fare computed and PNR allocated. Optionally, it may HAS-A bookingStatus (which would be true for this assignment always) and bookingMessage (which may be “BOOKING SUCCEEDED” for this assignment always).

Booking should support Passenger as a null-able parameter for future extension. • You may add any class, any data member to a class, or any hierarchy as you need for implementation. Justify your design choice for them.

3.3     Interfaces
•   Constructors / Destructors: Proper constructor and destructor for every class

•   Copy Functions: Provide user-defined Copy Constructor and / or Copy Assignment Operator for a class if used in the design (should not be needed). Otherwise, block them.

•   Provide output streaming operator for every class to help output process as well as debugging

•   Class Station to have GetName() for accessing its name and GetDistance(.) to get distance to another station.

•   Class Railways to have GetDistance(., .) to get distance between a pair of stations. It should also have proper interface for making it a singleton IndianRailways

•   Class BookingClasses to have GetLoadFactor(), GetName(), IsSitting(), IsAC(), GetNumberOfTiers(), and IsLuxury() to get access to various BookingClasses properties. Depending on the polymorphic hierarchy, these methods may be non-polymorphic and / or polymorphic (and in some case pure) in BookingClasses and its various derived classes. Consider making them const methods.

•   Class Booking to have ComputeFare() to implement the fare computation logic. Should it be virtual (polymorphic) for future extensions?

•   You may add any interface to a class (or private / protected methods) as you need for implementation. Justify your design choice for them.

3.4      Constants
The following should be static constants in appropriate classes:

•   Load Factors of various BookingClasses

•   Base Fare Rate: Rs. 0.50 / km

•   AC Surcharge: Rs. 50.00

•   Luxury Tax: 25% on booking amount

3.5     Statics
•   Class Date to have month and day names.

•   Class Railways to have sStations (list of stations) and sDistStations (distance between stations).

•   Class BookingClasses to have load factors.

•   Class Booking to have sBaseFarePerKM, sBookings (list of bookings done), sBookingPNRSerial (next available PNR), sACSurcharge, and sLuxuryTaxPercent

•   You may add any static to a class as you need for implementation.

3.6      Errors & Exceptions
•   All Booking requests are taken to be correct. That is, the Staions as mentioned - do exist, the Date is valid (in future), and no invalid BookingClass is requested

•   There is no error in input, processing, or output.

•   No error or exception handling to be incorporated in the design for this assignment. However, structure the code flow well so that they can be incorporated later with minimal changes (adhering to the need of flexibility).

4       Low-Level Design
Based on the High Level Design (HLD), we now perform the Low Level Design (LLD). LLD makes use of the specific constructs and idioms of C++.

4.1      Design Principles
The following design principles may be adhered to in the LLD:

•   Encapsulation

–    Maximize encapsulation for every class

–    Use private access specifier for all data members that are not needed by derived classes, if any. Use protected otherwise.

–    Use public access specifier for interface methods and static constants and friend functions only.

•   STL Containers

– Use STL containers (like vector, map, hashmap, list, etc.) and their iterators. Do not use arrays – Use iterators for STL containers. Do not use bare for loops.

•   Pointers & References

–    Minimize the use of pointers. Use pointers only if you need null-able entities

–    If you use pointer for dynamically allocated objects (should be minimized), remember to delete at an appropriate position.

–    Use const reference wherever possible.

4.2         Design of Classes, Data Members & Methods

This is left as an exercise in the assignment. Design based on the HLD and the principles and document well.

5       Implementation
After completing the LLD, we perform the coding (implementation). In this we adhered to a set of basic guidelines and code organization.

5.1       Basic Coding Guidelines

An indicative set of guidelines are listed in Section A. You may add more on your own.

5.2      Code Organization
Ideally, the definition of every class (or hierarchy) should be put in a corresponding .h file with the static definitions and method implementations in the respective .cpp. The application should be in Application.cpp file. However, for simplicity, it would be acceptable if all the codes are put in the Application.cpp file with the application.

6       Test Plan
We also need to prepare a test plan to test the implementation at different stages of development so that better quality and productivity can be ensured. Variety of test processes are common. We shall follow two of these in the current assignment.

6.1      Unit Tests
This is typically the basic test process which is engaged during development (however, it may be useful for future testing and debugging as well). In this, we test every class as it is implemented. We test all non-static & static member functions and friend functions. For a class hierarchy, the unit test is done typically at both concrete classes and the overall hierarchy levels specifically checking the polymorphic methods.

For the purpose of understanding, in Section B we illustrate the test plan and test function for a few unit cases for the Fraction class we have developed in Assignment 2.

6.2      Application Test
After the units have been tested, we integrate them into the application and test various scenarios for the application. A sample test application was provided for the Fraction class in Assignment 2. However, since it was just a single class application, the application code looked pretty much like the unit test application code with the exception of the comparison with golden data.

Like the units, we again need to enumerate scenarios for the application in the test plan and write the application test.

In addition, a sample test application for booking is given in Section C with the expected output in Section C.1. Your codes should pass this test application too.

7      Tasks
The following tasks are to be completed for the assignment:

1.    Design: Complete the HLD and the LLD. Document the salient points from your design in Design.txt. Follow the quality guidelines and design principles outlined above.

2.    Implementation: Implement the LLD in C++ following the basic coding guidelines (Section A).

3.    Test Planning: Write a unit test and application test plan in Testplan.txt covering all scenarios. Note that no wrong input or erroneous data situation is to be handled. For example, a Date specified will always be valid. So plan tests based only on correct input data.

4.    Testing: Implement unit test and application test codes and perform testing. For application testing, test with the application given in Section C as well as the application developed by you from the testplan.

More products