Java代写:CAB302 Test Driven Development

代写一个GUI程序,需要采用TDD(Test Driven Development)的软件开发模式。

Section 1: Learning Objectives

  • To experience team-based program development using an approach similar to test driven development.
  • To develop a Graphical User Interface.
  • To develop your skills in object oriented design including: inheritance, encapsulation and polymorphism.
  • To develop your skills implementing software patterns.
  • To demonstrate your ability to write clear, understandable program code.

Section 2: Your Tasks

You must obtain the incomplete source tree from the assignment 2 repository on BitBucket. The link to obtain the repository is listed above.

  • You will need to provide a solution to a problem written in the Java programming language.
  • The necessary functionality of your solution is described in this specification document.
  • In addition, you will be provided with a ‘Javadoc’ Application Programming Interface specification.
  • You must develop comprehensive test suites in JUnit for the classes produced by your partner.

Section 3: Scenario

Pizza Palace is a restaurant in West End, Brisbane. Last year, they had a group of students from Kingsland University of Technology develop a logging system that recorded orders placed at their restaurant. They would now like to produce a system that interprets the logs and displays the information on a Graphical User Interface (GUI).

Section 4: Downloading Code

You need to download some pre-existing code from a repository on BitBucket. The link for the repository is provided on the first page. You should import the repository into Eclipse using the steps outlined in the GitForPracs document available on Blackboard. You can find this document using the following steps: Blackboard->Learning Resources-> Help Guides and Other Resources.

Section 5: Problem Details

Your task is to write a Java program to analyse log files and display the derived information to a GUI. Each log file contains information about a set of pizza orders split into two main sections:

  1. Information about the pizza being ordered; and
  2. Information about the customer ordering the pizza.

There are certain constraints regarding the pizzas and customers which your program must adhere to. Here, we describe the constraints relating to pizzas and the customers, then we outline the log file and finally, describe the functionality required for the GUI.

Pizzas

Here are some details about the restaurant’s pizzas:

  1. The restaurant sells three types of pizzas: margherita, vegetarian and meat lovers. The toppings of each of the pizzas and prices are presented in Table 1. No other type of pizzas are available nor are any changes to the pizzas allowed.
  2. Each topping has a set unit cost for being included on a pizza as shown in Table 2. No other toppings are allowed.
  3. The restaurant keeps track of the time that a pizza was ordered and delivered. A pizza takes at least 10 minutes to cook and is thrown out after 1 hour (including delivery time).
  4. The restaurant begins taking orders at 7:00pm (when the kitchen opens) and stops taking orders at 11:00 pm (when the kitchen closes) Australian Eastern Standard Time. Deliveries may continue after 11:00 pm.
  5. At least one pizza must be ordered for the order to be valid.
  6. A customer may order more than one of the same type of pizza within the same order. However, if they want to purchase another type of pizza, then that must be in a separate order.
  7. The maximum number of pizzas in any one order is 10.
  8. You need to track details about the pizzas being ordered. For example, you need to record how much each pizza costs to make (calculated from its toppings) and how much each pizza sells for. You also need to calculate the order cost (cost per pizza multiplied by quantity of pizzas ordered), the order price (sales price per pizza multiplied by quantity of pizzas ordered) and the profit made per order (order price minus order cost).
  9. Each pizza contains a human description of their type (either “Margherita”, “Vegetarian” or “Meat Lovers”).

Customers

Here are some details about the restaurant’s customers:

  1. There are three types of customers: those who come to the restaurant to pick up their pizza(s), those who have their pizza(s) delivered by a driver and those who have their pizza(s) delivered by a drone.
  2. Each customer has a name, a mobile number, a location specified in x and y co-ordinates and a human understandable description of their type (either “Pick Up”, “Driver Delivery” or “Drone Delivery”).
  3. The name of the customer is between 1 and 20 characters long and cannot be only white spaces.
  4. The mobile number must be 10 digits long and begin with ‘0’.
  5. The x and y location of the restaurant is 0, 0.
  6. The customer’s x location indicates the number of blocks east or west of the restaurant that the customer is located. A value of 5 means that the customer is located 5 blocks east, while a value of -5 means that the customer is located 5 blocks west.
  7. The customer’s y location specifies the number of blocks north or south of the restaurant that the customer is located. A value of 5 means that the customer is located 5 blocks north, while a value of -5 means that the customer is located 5 blocks south.
  8. If the customer chooses to pick up their pizza then their location is always 0,0.
  9. You need to calculate the distance travelled to deliver a pizza in terms of blocks. If the customer chooses to have their pizza delivered by a drone, then the distance is equal to the Euclidean Distance (shown in Formula 1) between the restaurant and the customer. If the customer chooses to have their Pizza delivered by a driver, then distance is equal to the Manhattan Distance (shown in Formula 2) between the restaurant and the customer. If the customer decides to pick up the pizza then the distance travelled is 0. A description of Euclidian and Manhattan distance is provide in Figure 1.
  10. The restaurant will not deliver if the customer is at the restaurant.
  11. The restaurant will not deliver is the customer is more than 10 blocks north, south, east or west from the restaurant - however, the restaurant will deliver a distance greater than 10 blocks. For example, a driver would deliver to a customer located at (5,6) despite have a Manhattan distance of 11.

The Log Files

The log files are text documents formatted as comma separated value (CSV) files. A log is created daily, with its filename specifying its date. Each line holds a record of a single order placed by a customer. The format of each line, as well as some of the constraints, are listed follows. order-time, delivery-time, customer-name, customer-mobile, customer-code, customer-x-location, customer-y-location, pizza-code, pizza-quantity

  • order-time - The time that the order was placed formatted as “hh:mm:ss” (where hh is hours, mm is minutes and ss is seconds) specified in 24 hour format.
  • delivery-time - The time that the delivery was made formatted as “hh:mm:ss” (where hh is hours, mm is minutes and ss is seconds) specified in 24 hour format.
  • customer-name - A string that specifies the name of the customer.
  • customer-mobile - A string that specifies the customer’s mobile number.
  • customer-code - A string that specifies if the customer will travel to the restaurant to pick up the pizza (“PUC”) or have it delivered to their house either it by a drone (“DNC”) or by a driver (“DVC”).
  • customer-x-location - An integer that specifies the number of blocks east or west of the restaurant that the customer is located
  • customer-y-location - An integer that specifies the number of blocks north or south of the restaurant that the customer is located.
  • pizza-code - A string specifying the type of pizza that the customer is ordering, either margherita(“PZM”), vegetarian (“PZV”) or meat lovers (“PZL”).
  • pizza-quantity - An integer that specifies the number of pizzas ordered.

The GUI

You need to design and implement a graphical user interface (GUI). The GUI does not need to be elaborate; however, it must provide the functionality outlined below. Throughout this section, we will use the term “PAG” which means Perform a Gesture. The GUI implementation is left to your own reasonable discretion, so this term allows us to abstract otherwise specific widget actions such as “press a button”.

  1. PAG to load a Log file. The user must be able to load a log file that is saved on disk. The functionality to request opening a file can be done via JButton or similar and actual files can be chosen via a JFileChooser. Once the log file is chosen it should be processed and analysed by the rest of the system.
  2. PAG to display information. Once the information is processed the user can PAG to display the information contained in the log files. Separate components should be used to display information about the customers and the pizzas. A component such as a JTextField or JTable is suitable to display this information. The information needs to be user friendly, so the codes used to describe pizzas and customers should be translated to into pizza and customer ‘types’ using descriptive language (Margherita, Meat Lovers, Vegetarian/Pick Up, Driver Delivery, Drone Delivery). The user must not be allowed to perform this gesture unless the log file has successfully been loaded. Specifically, the following information needs to be presented for each order and customer.
  3. PAG to perform and display calculations. Once the information is processed the user can PAG to calculate the total profit made and total distance travelled for all orders made that day. Again, separate components should be used to display each total. A component such as a JTextField is suitable to display each total. The user must not be allowed to perform this gesture unless the log file has successfully been loaded.
  4. PAG to reset. Finally, the user should be able to reset and clear all the information from the screen. All components should be also reset to their initial states. The user must not be allowed to perform this gesture unless the log file has successfully been loaded.

The GUI should also report to the user when each functionality has been successfully completed or when any error has occurred.

Detailed Tasks

The source tree for the assignment includes the packages shown in Figure 2. The key subdirectories are:

  • src: This directory contains all the source code. As a team you will need to complete code for system functionality in the asgn2Customers, asgn2Pizzas, asgn2Resurant, asgn2GUis, asgn2Wizards packages as well as test code in the asgn2Tests package.
  • doc: This directory contains the API. It has been generated using the Javadoc tool on a complete system.
  • logs: This directory contains some test logs.
  • libs: This directory contains the libraries for JUnit and Hamcrest.

Tasks by Package

Please Note: For all packages and classes carefully check that you have spelt the file’s name correctly, otherwise it will not work with our automated marking software.

PACKAGE: asgn2Pizzas

This package contains classes that represent pizzas at the restaurant as well as a class that creates those classes using the factory method pattern and an enumeration that represents pizza toppings.
There are three types of pizzas represented by three concrete classes which inherit from a single abstract Pizza class.
The classes in this package are as follows:

  • Pizza: An abstract class representing a pizza made at the restaurant. It contains a method to calculate the cost of the pizza derived from its toppings as well as methods to retrieve the quantity of pizza ordered, the cost and price per pizza and per order, the profit made on the order and if the pizza contains a specific topping or not. It also contains a method to retrieve the type of pizza which corresponds to the user-friendly description outlined. The class also contains a method that can be used to test equivalence between Pizza Objects (which is implemented for you and you do not need to test). The class keeps track of when the order was made and when the pizza was delivered (either in the restaurant or to the customer’s house).
  • MargheritaPizza: A concrete class that represents a margherita pizza.
  • MeatLoversPizza: A concrete class that represents a represents a meat lovers pizza
  • VegetarianPizza: A concrete class that represents a vegetarian pizza

The specific toppings, costs and prices for each of the concrete Pizza subclasses are outlined.

In addition, the package also contains the following class:

  • PizzaFactory: A class that contains a single method getPizza, which uses the factory method pattern to construct one of the three concrete Pizza subclasses. The class choice is specified by the pizzaCode parameter which has one of three valid values as outlined.
  • PizzaTopping: An enumeration that contains a set of pizza toppings and their associated cost. It also contains a method to retrieve a cost for a specific topping. You do not need to make any changes to this enumeration nor do you need to provide any tests for it.

PACKAGE: asgn2Customers

This package contains classes that represent customers at the restaurant as well as a class that creates those classes using the factory method pattern. There are three types of customers represented by three concrete classes which inherit from a single abstract Customer class.

  • Customer: An abstract class representing a customer at the restaurant. It contains methods to retrieve the customer’s name, mobile number, x and y locations, all of which is derived from the information in the log file. It also contains methods to retrieve the distance travelled from the restaurant, a method that can be used to test equivalence between Customer Objects (which is implemented for you and do not need to test), and retrieve the customer type which corresponds to the user-friendly description outlined in Section 5.4.
  • PickupCustomer: A concrete class that represents a customer who has chosen to pick up their pizza.
  • DriverDeliveryCustomer: A concrete class that represents a customer who has chosen to have their pizza delivered by a driver.
  • DroneDeliveryCustomer: A concrete class that represents a customer who has chosen to have their pizza delivered by a drone.

Each of the Customer subclasses has to overwrite the getDeliveryDistance method using the formulas outlined in Section 5.2.
In addition, the package also contains the following class:

  • CustomerFactory: A class that contains a single method getCustomer, which uses the factory method pattern to construct one of the three concrete Customer subclasses. The class choice is specified by the customerCode parameter which has one of three valid values as outlined in Section 5.3.

PACKAGE: asgn2Restaurant

This package contains classes that act as a bridge between the GUI, the log files and the classes in the asgn2Customers and the asgn2Pizzas packages. It contains the following classes:

  • LogHandler. A class that contains methods that use the information in the log file to return Pizza and Customer objects. The class contains methods that return either an individual Pizza object (createPizza) and Customer object (createCustomer) as well as methods that return an ArrayList of Pizza objects (populatePizzaDataset) and ArrayList of Customer objects (populateCustomerDataset). Note that the objects in both ArrayLists should in the same order that they appear in the log file.
  • PizzaRestaurant. This class acts as a ‘model’ of a pizza restaurant and contains an ArrayList of Pizza objects and an ArrayList of Customer objects. It contains a method that can populate the ArrayLists (processLog) (via other methods in the system) and several methods to retrieve information about the ArrayLists (geCustomerByIndex, getPizzaByIndex, getNumPizzaOrders, getNumCustomerOrders, getTotalDeliveryDistance, getTotalProfit) and reset the ArrayLists (resetDetails).

PACKAGE: asgn2Exceptions

This package contains classes to represent different types of exceptions. You do not need to modify or test any of the classes in this package.

  • PizzaExceptions. A class that represents exceptions related to the construction and handling of Pizza objects.
  • CustomerExceptions. A class that represents exceptions related to the construction and handling of Customer objects.
  • LogHandlerExceptions. A class that represents exceptions related to reading in the log such as incorrect format or exceptions related to input/output.

PACKAGE: asgn2GUIs

This package contains a single class:

  • PizzaGUI. This class is the graphical user interface for the rest of the system. Currently it is a ‘dummy’ class which extends JFrame and implements Runnable and ActionLister. It should contain an instance of an asgn2Restaurant.PizzaRestaurant object which you can use to interact with the rest of the system. You may choose to implement this class as you like, including changing its class signature - as long as it maintains its core responsibility of acting as a GUI for the rest of the system. You can also use this class and asgn2Wizards.PizzaWizard to test your system as a whole.

PACKAGE: asgn2Wizards:

This package contains a single class:

  • PizzaWizard. This class is the ‘entry point’ to the rest of the system and provides a public static void main method. At the moment, this just calls the asgn2GUIs.PizzaGUI class. You can probably leave the class as it is, however, you must make sure that it is the one and only entry point to the rest of the system.

PACKAGE: asgn2Tests:

This package contains the JUnit test classes. The classes contained in this package are:

  • PizzaTests that tests the asgn2Pizzas.MargheritaPizza, asgn2Pizzas.VegetarianPizza, asgn2Pizzas.MeatLoversPizza classes. Note that an instance of asgn2Pizzas.MeatLoversPizza should be used to test the functionality of the asgn2Pizzas.Pizza abstract class.
  • CustomerTests that tests the asgn2Customers.PickUpCustomer, asgn2Customers.DriverDeliveryCustomer, asgn2Customers.DroneDeliveryCustomer classes. Note that an instance of asgn2Customers.DriverDeliveryCustomer should be used to test the functionality of the asgn2Customers.Customer abstract class.
  • PizzaFactoryTests that tests the asgn2Pizzas.PizzaFactory class.
  • CustomerFactoryTests that tests the asgn2Customers.CustomerFactory class.
  • LogHandlerPizzaTests that tests the methods relating to the creation of Pizza objects in the asgn2Restaurant.LogHander class.
  • LogHandlerCustomerTests that tests the methods relating to the creation of Customer objects in the asgn2Restaurant.LogHander class.
  • RestaurantPizzaTests that tests the methods relating to the handling of Pizza objects in the asgn2Restaurant.PizzaRestaurant class as well as processLog and resetDetails.
  • RestaurantCustomerTests that tests the methods relating to the handling of
    Customer objects in the asgn2Restaurant.PizzaRestaurant class as well as processLog and resetDetails.

Note the naming convention is to use the plural form (i.e. MyClassTests.java) rather than the singular form (i.e. MyClassTest.java).

Section 8: Testing and Exceptions

The following principles need to be followed when dealing with testing and exceptions in Assignment 2. Please note that this these principles only refer to the classes in following packages: asgn2Pizzas, asgn2Customers, asgn2Restaurant, asgn2GUIs, asgn2Wizards. Exceptions in your JUnit tests should be handled as per the standard covered in lectures and tutorials.

What types of errors are there and where should errors be handled?

Some parts of the API deliberately lack detail regarding when exceptions should be thrown, for example the constructors of the asgn2Pizzas.Pizza and asgn2Customers.Customer subclasses say something similar to “throws exception if supplied parameters are invalid”. However, the exceptions (and where they should be handled) can be broken down into the following cases:

Log File Type Errors

Errors associated with reading the log file should be dealt with in asgn2Restuant.LogFileHandler. These errors include input/output errors (for example: file not found) and errors associated with the wrong type which will cause parse errors. The required type for each field are listed in Table 4. Most of these types are straightforward, except for the mobile number field that is a String rather than a numeric type, since it contains constraints atypical to numbers (e.g. must start with a ‘0’) and is not used to perform traditional numeric operations (e.g. you don’t add together two mobile numbers).

Note that if there is an error in the log file then neither the customers nor the pizzas dataset should be populated.

Constraint Violation Errors

These constraints should be handled by subclasses of the asgn2Pizzas.Pizza and asgn2Customers.Customer classes. Most of these are logic based (e.g. a delivery cannot be made to certain locations or a pizza cannot take longer to cook than a specified duration). However, some are based on format or other things (e.g. a mobile number needs to be in the correct format).

Incorrect Pizza and Customer Codes

There are only three valid pizza and customer codes. Any invalid codes should be handled by the asgn2Pizzas.PizzaFactory or asgn2Customers.CustomerFactory classes.

System Errors

Broader system errors (e.g. those involving accessing multiple instances of the asgn2Pizzas.Pizza or asgn2Customers.Customer classes) should be handled by the asgn2Restuant.PizzaRestaurant class.

Other Errors Not Specified

Section 5 has covered specific errors for this system, however, there are some general errors (for example: accessing an invalid index) which have not been discussed. These errors should also be accounted for in your solution, particularly, if we have discussed these errors during the lecture.

If there is any doubt about which errors should be included, then you should ask the teaching team (in particular the unit co-ordinator). Since part of the challenge for this assignment is to identify the errors, you should ask the teaching team member privately (either face-to-face or by email) rather than on a public forum (e.g. Facebook).

Propagating Exceptions Without Violating the API

Exceptions should be propagated throughout the system. This means that if MethodA() calls MethodB() and MethodB() calls MethodC(), then exceptions thrown by MethodC() should be thrown to MethodB() and in turn to MethodA()(note: this is different to Assignment 1). This is because exceptions in the backend classes need to be passed to the asgn2GUIs.PizzaGUI class and displayed to the user. However, you still need to conform with the API regarding which methods can throw which exceptions (so you can’t change a method signature to thrown an additional exception) and only the exceptions in the asgn2Exceptions package should be thrown (PizzaExceptions, CustomerExceptions, LogHandlerExceptions).This means that you have to ‘translate’ other types of exceptions into one of the asgn2Exceptions types and requires you to follow the following steps (In general, it is better to use case 1 rather than case 2).

Case 1: Program Defensively

In this case, you want to throw an exception before another exception occurs. You should check for the condition that would throw the exception and throw one of the custom asgn2Exceptions instead.

Case 2: Program Reactively

Sometimes you cannot perform a check before an exception is thrown. In this case, you want to catch that original exception within the method and throw one of the asgn2Exceptions instead. This requires the use of a try/catch block.

If you are able to catch more specific Exceptions, or multiple specific Exceptions within the same try/catch block, then you should do so.

Rethrowing the Same Exception

There are times when an exception occurs and the API says that that exception should be thrown, but you want to do something else before you throw that exception (for example, setting a variable).
In this case the exception should be thrown within the catch block.

Section 9: Test Driven Development and Teams

Breakdown of Work

One of the keys aims of this assignment is to give you experience working in a team based test driven development scenario. Therefore, you should be designing and implementing the test cases for your partner and vice versa. As such, the breakdown of the work should be as listed in Table 5.

For most of the classes you will be able to work individually (individual model classes and individual test classes). However, sometimes both team members will need to work on the same class and sometimes on the same method (shared model classes).

Forming Teams

Over the years we have run this assignment, there have always been people who have either requested that they be allowed to do the assignment alone (the right way of going about it) or simply handed in an assignment that is solely their own work and hoped that we’d be ok with it (the wrong way of going about it). Please ask if there is a good reason why you cannot make work in a pair but generally the answer will be no unless there are specific and very significant obstacles in the way.

In the past we have had a number of students who work full time contact me to express their concerns about working with other people, with some worried about having opportunities to pair up with other students. I had have successful collaborations which involve coding with people on the other side of the world, and this is increasingly common. The key of course is to establish the pair. Once you have had a couple of face to face meetings, it will usually work. Mostly working full time is not a sufficient barrier - I have had people working for mining companies in remote locations with lousy internet connectivity, and I have allowed them to work alone. Those i n the city should normally be able to connect sufficiently, with occasional face to face meetings.

Section 10: Additional APIs

We will cover the vast majority of work required to complete the assignment in class. However, there are some additional APIs which you will need to read yourself. This is not an uncommon practice in Java software development since the JDK is large and so programmers regularly use unfamiliar APIs. Note you should have already covered the desired functionality in your previous programming units, so you should know what needs to be done even if you don’t know explicitly how it should be done in Java. Here, we have listed the some of the APIs and provided links to the Official Java Tutorial.