Java代写:COSC1284 Ticketing System

代写一个大型应用程序,实现一个售票系统。

Backround information

For this assignment you need to write an object-oriented console application in the Java programming language which adheres to basic object-oriented programming principles shown below:

  • a) Setting the visibility of all instance variables to private.
  • b) Only using static attributes and methods when appropriate.
  • c) Encapsulating both the data for a class and the methods that work with and/or manipulate that data within the same class.
  • d) Using superclass methods to retrieve and/or manipulate superclass properties from within subclass methods where necessary.
  • e) Taking advantage of polymorphism wherever possible when invoking methods upon objects that have been created.

The scenario we are modelling is that of ticketing system for a ferry company in which customers who wish to travel on the ferry can make bookings for a “standard” passenger vehicle or an oversized vehicle (delivery truck, passenger coach, etc) to be transported on the ferry.

A standard passenger vehicle booking on the ferry incurs a booking fee of $100 plus an additional $20 booking surcharge for each person travelling in the vehicle (including the driver).

A standard size passenger vehicle is defined as being less than or equal to one meter in height.

A ferry booking for an oversized vehicle will attract a surcharge due to their larger size, so the weight and category for all oversized vehicles needs to be recorded upon boarding.

Getting Started

In this assignment you will be required to implement an object oriented program that models some of the basic functionality that may be required to handle both “regular” Vehicles and ‘oversized’ Vehicles in the Vehicle Booking System described above.

This task is divided up into several stages, each of which corresponds to the concepts discussed during the course as shown below:

  • Stage 1 - Vehicle class (Writing classes)
  • Stage 2 - BookingSystem (Arrays of objects)
  • Stage 3 - OversizedVehicle class (Inheritance / subclasses)
  • Stage 4 - BookingSystem updates (Polymorphism)
  • Stage 5 - Exception Handling (Exception Handling)
  • Stage 6 - Persistence to file (File Handling)
  • Code Quality (General Concepts)

There is no Startup code for this assignment you are expected to write the entire program yourself.

A single class called DateTime has been provided to help make working with dates easier than using the inbuilt Java classes.

Your task begins with the implementation of the Vehicle class.

It of course goes without saying that working your way through the learning materials for the corresponding weeks highlighted above is strongly recommended before tackling each of the stages in this assignment.

You are strongly encourage to review the course materials for the corresponding weeks before starting on the relevant stage, to ensure that you have sufficient grasp of the underlying concepts to proceed.

Stage 1 - Vehicle class Design / Implementation

Both “normal” Vehicle and ‘oversized’ Vehicles share common details (such as the registration number, make, year, a description, booking id, and the number of passengers (including the driver) which are encapsulated in this superclass.

Some tips below should help you to design and write the Vehicle class:

A) Create the Vehicle Class

The following attributes should be defined in your Vehicle class.

Instance variable Type
regNo String
make String
year int
description String
bookingID String
bookingDate DateTime
numPassengers Integer
Constants Type Value
BOOKING_FEE int 100
PASSENGER_SURCHARGE int 20

B) Constructor

You should define a constructor in your Vehicle class.

You should not have a no argument constructor.

The constructor should be responsible for initialising: regNo, make, year and description to the values provided by the creator of the object.

The constructor should initialise the booking id to “N/A”

C) Accessors (getters)

A simple accessor (getter) should be implemented for regNo.

No other simple accessors should be implemented.

D) Mutators (setters)

No simple setters should be implemented for any of the instance variables..

E) Record Passenger Numbers (Private)

A private method for recording the number of passengers travelling in the vehicle should be implemented.

This method should return false if an attempt is made to set the passenger numbers to any value less than 1 or greater than six.

Otherwise, the number of passengers for the vehicle should be set to the number provided when this method is called.

Floating point numbers are not permitted, the number of passengers must be represented as an integer value.

This method should be called by the ‘book’ method described below.

If successful the method should return true.

F) Book

A ‘book’ method should be implemented, which calculates and returns a booking fee based on a fixed value booking fee + a surcharge of $20 for each person (including the driver) that is travelling with the vehicle. This method uses negative values to indicate any errors that prevented the booking from being completed. See the details below.

This method should accept two parameters. One for the number of passengers and another that accepts a DateTime object set to the date of the booking. The class for creating the DateTime object has been provided for you on Blackboard.

Examine this class because it has a number of methods you may find useful to use when working with dates in your application.

Creating a DateTime object can be done in the following manner.

1
DateTime date = new DateTime(day, month, year));

If the number of passengers is not valid then it should return - 1.0 to the caller of the method and must not complete the booking process.

If the date is in the past then, then it should return - 2.0 to the caller of the method and must not complete the booking process.

If the number of passengers and the date ARE valid then it should: Set the booking id to a concatenation of the:

regNo + a date in the format DDMMYYYY

Retrieving the 8 digit format of the date can be done in the following manner.

1
date.getEightDigitDate();

For example a car with the registration “AAA123” booked on the 24 August, 2017 should have a booking id of:

SIM47924082017

Set the bookingDate to the date passed into this method.

Calculate and set the bookingFee to the appropriate value.

Return the booking fee to the caller of the method.

Note that “returning” a value does not mean printing a value to the screen. The value should be returned to the code that calls the function and the calling code is responsible for deciding what to do with the data provided.

G) Get Vehicle Details

A method should be implemented which returns a description of the vehicle.

This method should build a string and return it to the calling method.

The returned string should be formatted in a human readable form.

The description must include labels and values for all the instance variables depending on whether a booking has been made.

If the booking id is equal to “N/A” then the number of passengers, bookingDate and the fee should not be included in the description.

If the booking id is not equal to “N/A” then it should also return all the details including, bookingId, bookingDate and the number of passengers and the booking fee.

The method should return a formatted string such that the data is presented in a human readable format of two columns as shown in the examples below.

Note that “returning” a value does not mean printing a value to the screen. The value should be returned to the code that calls the function and the calling code is responsible for the actual printing.

The formatting of the string can be achieved by using the format method on the String class which operates in the same way as the printf statement you learned about earlier in the course.

1
String firstLine = String.format("%-20s %s\n", "Reg Num:", regNo);

Example 1:
Reg Num:          SIM479
Make:             Honda
Year:             2007
Description:      White Sedan
Booking Ref:      N/A

Example 2:
Reg Num:          SIM479
Make:             Honda
Year:             2007
Description:      White Sedan
Booking Ref:      SIM47928082017
Booking Date:     28/08/2017
Num Passengers:   4
Fee:              $180.00

Stage 2 - BookingSystem class (basic functionality)

Now that the attribute and functionality required for a regular sized vehicle has been modelled and encapsulated in the Vehicle class described above in Stage 1. Here, you will begin with the implementation of the BookingSystem application class, which will use an array, ArrayList or a HashMap of Vehicle references called vehicles to store and manage vehicles that are added to the system by the user.

You are not permitted to use streams from Java 1.8. You must use either an array, ArrayList or a HashMap to store the collection of your vehicles.

  • 1.) You should create a class called ‘BookingSystem’.
    • A) create a class called ‘BookingSystem’
    • B) this class should present a menu to the user for interacting with the program.
  • 2.) You should implement a menu feature in the BookingSystem class, for which options are presented to:
    • A) Seed data,
    • B) Add new Vehicles to the system,
    • C) Display Vehicle details and
    • D) Book passage on the ferry.

A screen shot showing the presentation of this menu is shown below.

You must implement the menu as shown.

Do not change the options or the inputs for selecting the menu options.

(Note: the letters on the right represent what the user must type to use that feature. In other words, to add a new vehicle object the user must input ‘A’. The solution should be case insensitive, that is the user should be able to enter either ‘a’ or ‘A’)

*** Vehicle Booking System Menu ***
Seed Data                  A
Add Vehicle                B
Display Vehicles           C
Book Passage               D
Exit Program               X
Enter selection:

Your task is to work on the implementation of this initial BookingSystem class by implementing the functionality for the features shown in the menu.

A description of the functionality that needs to be implemented for each of these features is provided below.

A) Menu System & Seed Data method

You should implement a method called ‘seedData’ that pre-populates the vehicles collection with 4 sample vehicles. When this menu item is selected 4 hard coded vehicles will be instantiated and added to the collection.

  • Two regular sized vehicles that HAVE been booked
  • Two regular sized vehicles that HAVE NOT been booked

If this option is not selected at runtime, then the collection of vehicles should be empty.

B) Add Vehicle

Create a class called ‘BookingSystem’ and implement the menu shown above.

This first feature ‘Add Vehicle’ should prompt the user to enter all relevant details for a “regular” Vehicle.

This will be updated later to include Oversized vehicles, but initially you are only required to handle adding regular sized vehicles.

Once the user has entered the required details, the program should then create a new Vehicle object accordingly, passing along the details the user has supplied.

Example:
Enter vehicle registration:          SIM479
Enter vehicle make:                  Honda
Enter vehicle year:                  2007
Enter vehicle description:           White Sedan

New Vehicle added successfully for registration SIM479.

After the object has been created it should be added to the next (empty) spot in the array or collection instance that you are using to store the vehicle objects.

(Note: vehicle registration numbers must be unique in the BookingSystem, so you will need to validate the registration number entered by the user to make sure that there is not already another vehicle with the same registration number in the system.

This should be done by searching the current collection and checking for a duplicate registration number you should not modify the prescribed constructor for the Vehicle class nor should you implement automatic generation of unique registration numbers. )

If the registration number already exists within the array/collection of vehicle objects then a suitable error message should be displayed and the program should go back to the menu immediately without creating or storing a new Vehicle object in the array / collection.

This means that you should perform this check prior to creating the Vehicle object.

Example 1:
Enter vehicle registration:          SIM479
Enter vehicle make:                  Honda
Enter vehicle year:                  2007
Enter vehicle description:           White Sedan

New Vehicle added successfully for registration SIM479.

Example 2:
Enter vehicle registration: SIM479
Error - Registration SIM479 already exists in the system!

If you are unsure of how to check for a duplicate registration number then you can skip the validation for now and come back to it later.

You are not permitted to implement auto generated user inputs such as registration numbers, but must validate those entered by the user.

C) Display Vehicle Information

This feature should display the details for all objects currently stored in the array / collection of Vehicle references described above to the screen, by using a loop to step through the array / collection and calling the getDetails() method for each object in the array/collection and printing the returned string to the console.

D) Book passage

This feature should begin by prompting the user to enter the registration number of the vehicle for which they wish to book passage. Once the user has entered the registration number the feature should then attempt to locate the corresponding vehicle object within the array / collection of Vehicle references described above.

If a matching vehicle with the specified registration number was not found then a suitable error message should be displayed to the screen.
Example:

Enter registration number: AAA123
Error - registration number not found

Otherwise the feature should then proceed to prompt the user to enter the requested date of the booking and the number of passengers travelling.

If the booking was not accepted a suitable error message indicating the reason the booking failed should be displayed on the console.

If the booking was accepted, then the booking cost should be returned by the method call and printed to the console.

Stage 3 - Oversized Vehicle design / implementation

For an oversized vehicle the ferry company needs to record the vehicle weight and category (which is used in determining the weight surcharge for booking fee calculations), on top of the information that is already being stored for a standard vehicle booking.

You should address this new functional requirement by implementing an OversizedVehicle class, which extends the basic Vehicle class, as follows:

A) Create the Oversized Vehicle class by extending the Vehicle class

Extend the Vehicle class to define a new subclass OversizedVehicle, which includes new instance variables for the weight (an int) and category (a String) for the OversizedVehicle.

Define constant values representing the three weight surcharge rates, as described in the preamble.

NOTE: You should not need to redefine any of the instance variables that were defined previously in the Vehicle superclass in this OversizedVehicle subclass. Whilst a regular sized vehicle has a height it is not important to record this value for regular sized vehicles, so this attribute is placed in the oversized vehicle class.

Instance variable Type
weight double
category String
Constants Type Value
CLEARANCE_HEIGHT double Set at construction
LIGHT_VEHICLE_CHARGE double 10.0
MEDIUM_VEHICLE_CHARGE double 20.0
HEAVY_VEHICLE_CHARGE double 50.0

You should also define any other constants you feel are necessary to prevent repetition of hard coded values used in this class.

B) Implement a constructor

Implement a constructor for this OversizedVehicle subclass, which accepts the registration, make, year and description, and clearance height for the OversizedVehicle as parameters and stores the approprate values in the corresponding instance variables in the super class.

The constructor should take an additional parameter for storing the clearance height needed by the vehicle which should initialise the constant in this class.

You should not add the clearance height to the super class as an attribute because it is not a requirement of a regular sized vehicle class to store or make use of a height value.

The category instance variable should also be set to “N/A” initially.

NOTE: You should use the super() facility to pass on the relevant arguments to the superclass constructor.

C) Implement a unique method

Implement a private method called ‘recordWeight’ which accepts the recorded weight of the vehicle.

The weight instance variable should be set to the figure specified in the parameter.

If the vehicle weight has been recorded then the vehicle category should also be set to either “N/A”, “LIGHT”, “MEDIUM” or “HEAVY”, based on the vehicle weight, as per the information set out in the preamble.

D) Additional method

Add a new ‘book’ method that takes three parameters: numPassengers (int), date (DateTime), weight (double) so that it calculates and returns the booking fee for an OversizedVehicle, which is the sum of the basic fee that applies to every Vehicle and the weight surcharge for an OversizedVehicle.

This method should first check the clearance height of the vehicle and return -3.0 if the clearance height of the vehicle exceeds 3 meters.

If the clearance height is less than or equal to 3 then it should attempt to complete the booking by calling the super class version of the book method to complete the other basic checks. If the basic checks fail then the result should be returned to the caller of the method.

Finally, if the booking has been successful at this point it should calculate the surcharge based on the category of the vehicle and add this surcharge to the base booking fee.

Assign and return the result to the caller of the method.

Note that the applicable weight surcharge rate is determined by the vehicle category, as per the information presented in the preamble.

NOTES: You must use the super “reference” to invoke the book() method from the superclass, in order to calculate the base booking fee, so that it can be used as the basis for calculating the total booking fee for the current OversizedVehicle.

Note that “returning” a value does not mean printing a value to the screen. The value should be returned to the code that calls the function and the calling code is responsible for the actual printing.

E) Override getDetails method

Override the getDetails()method, so that it prints a full summary of the details for the current OversizedVehicle to the console.

If no weight is recorded then it should only add the clearance height to the basic details.

If a weight has been recorded then it should also include the weight and the category assigned to the
OversizedVehicle).

NOTE: The overriding version of the getDetails() method in this OversizedVehicle subclass will need to use the super “reference” invoke the corresponding method from the Vehicle superclass to get the basic vehicle details first.

Stage 4 - BookingSystem class (updated)

The next stage of this task is to update the BookingSystem application class implementation described in stage 2 so that it incorporates the ability to work with OversizedVehicles:

A description of the functions that need to be implemented for each of these features is provided below.

A) Seed Data

Update your seed method so that it now pre-populates the collection of vehicles with 4 regular sized vehicles and 6 oversized vehicles. The seeded data must contain the following variety of vehicles.

  • Two regular sized vehicles that HAVE been booked
  • Two regular sized vehicles that HAVE NOT been booked
  • Three oversized vehicles that HAVE BEEN booked. One from each of the categories (light, medium, heavy).
  • Three oversized vehicles that HAVE NOT BEEN booked.

B) Add Vehicle

Update your add vehicle function to now prompt the user to enter the height of the vehicle.

Once the user has entered all of the required information, if the height exceeds less than or equal to 1.0, a standard sized vehicle should be created.

Otherwise, a new OversizedVehicle object should be created.

Enter vehicle registration:  PUM234
Enter vehicle make:          Lexus
Enter vehicle year:          2007
Enter vehicle description:   Red Sedan
Enter vehicle height:        1.1

New oversized vehicle added successfully for registration PUM234

The object should be stored in the next available (empty) position in the same vehicle array/collection described previously in Stage 2.

Note: If you are using a standard array to store the vehicle objects in your BookingSystem then you should also increment the bookingCount variable to indicate that there is now one more booking object in the array (if you are using a standard array).

C) Book Passage (Updated)

This feature should begin by prompting the user to enter the registration of the vehicle for which they want to make a booking.

Once the user has entered the registration, the feature should then attempt to locate the corresponding vehicle object within the same vehicles array described previously in Stage 2.

If a matching booking object with the specified registration was not found then a suitable error message should be displayed to the screen, otherwise the feature should then proceed to check the type of the object that was found.

If the type of the specified object is a regular sized vehicle it should proceed with the booking as normal.

If the type of the specified object is an OversizedVehicle then the feature should prompt the user to enter the weight of the vehicle in question, and invoke the constructor of the OversizedVehicle class (note: you will need to use a typecast here) for the OversizedVehicle object, passing the weight entered by the user as a parameter.

Note that it is not necessary to re-prompt the user to enter another registration to search for if the registration was not found.

Enter registration number: RIC888
Enter day of month:        09
Enter month:               09
Enter year:                2017
Enter passengers:          4
Enter weight:              3.5
Booking for RIC888 on 11/11/2017 was successful.
The total cost of the booking is: $145.00

Stage 5 - Adding exception handling to existing functionality

It has been identified that there are potential issues with the booking process. Currently, these have been handled by returning a code to the user to indicate the source of the problem.

It has been decided that a better solution is to generate an exception with a custom error message that will inform the user of the problem that has occurred.

You should comply with these requests by making the following changes to your program.

NOTE: When you implement exceptions into your program you will need to modify your Vehicle, OversizedVehicle and BookingSystem classes to work with the exeptions.

Exceptions will be generated and thrown in the Vehicle and OversizedVehicle classes.

Exceptions will be caught and handled in the BookingSystem class.

A) Creating the Exception Class

Define your own custom Exception subclass type VehicleException, which represents an issue that occurs when attempting to record weight (for oversized vehicles) or when attempting to calculate the booking fee for a booking where the number or passengers or vehicle weight (for oversized vehicles) has not yet been recorded in the BookingSystem.

This VehicleException type should allow an error message to be specified when a new VehicleException object is created. No additional details need to be recorded for this new VehicleException type.

Your exception class should be named VehicleException and it should be a sub-class of the Java Exception class.

B) Generating Exceptions

Update the Vehicle class to instead generate and throw an exception with a custom error message that indicates whether the exception was caused by one of these two scenarios:

  • invalid passenger numbers
  • an invalid booking date.

Update the OversizedVehicle class to instead generate and throw an exception with a custom error message that indicates when the vehicle is too tall to fit on the ferry:

  • An oversized vehicle has a clearance height of greater than 3 meters.

C) Handling Exceptions

This VehicleExceptions should then be allowed to propagate back up to the BookingSystem class (ie. the exception should not be caught locally within the Vehicle or OversizedVehicle classes).

It will need to be caught and handled in an appropriate mannerin the BookingSystem class (by displaying the error message contained within the VehicleException object that has propagated up from the relevant method call).

Stage 6 - File Handling

This section of the program is designed to challenge and extend your problem solving skills and is meant for the HD component of the assignment.

It is expected that you will design your own solution for this feature.

Your tutor can comment on your solution, but will not tell you how to write this section of the assignment.

Your program should incorporate file handling functionality so that it writes the details for each vehicle object currently in the Booking System out to file when the program terminates (i.e. when the user selects the “Exit” option in the menu).

The data that was previously written out to file should then be read back in automatically when the program is started up again and the vehicle information within should be used to create an appropriate set of Vehicle and OversizedVehicle objects, which should be stored in the array or collection of Vehicle references described in Stage 2 above.

If the vehicle data file is not found in the local folder then the program should:

  • 1.) First check for the presence of a backup file and if found use this backup file for loading the data.
  • 2.) If loading from the backup file, display a message indicating that the data was loaded from a backup file.
  • 3.) If no backup file is found, display a message indicating that no Vehicle data was loaded and continue on to the program menu without reconstructing any objects.

All vehicle data should be written out to and read in from (the same) text file (containing the details for both Vehicle and OversizedVehicle objects in the Booking System).

The format that you write vehicle data out in is entirely at your own discretion as long as it is done to a text file.

One aspect of this task is to record any changes that have been made during the previous run of the BookingSystem application, so your file handling functionality must be able to handle the writing out and reading in of all details for both types of vehicles in such a way that the state of the BookingSystem at the point where the program was last exited is reconstructed in full when the program is started up again.

You can make any changes or include any additional methods that you deem necessary to the Vehicle / OversizedVehicle classes to facilitate the writing out and reading in of details for both vehicle types to satisfy this part of the specification.

Note that the program design described for the VehicleBooking, OversizedVehicle and BookingSystem classes in stages 1 - 5 does not fully support for what is required in this stage, so part of this task is identifying what aspects need to be considered and designing / implementing a solution accordingly to facilitate the writing out and reading in of details for both booking types for this functionality.

Remember that you will still be required to adhere to basic object-oriented programming principles (eg. encapsulation, information hiding, etc) when designing your solution for this aspect of the program.