DPSD - Project 1.0

Problem Description
In Project 1 you will build a Pizza Configuration Application. In this project you will build a system that allows a Pizzeria to manage pizza orders. Your system is for any Pizzeria anywhere.

Note: the next 4 homework projects will build and modify this same Pizza Configuration application. This means you may need to update your code before you can complete the next unit. This is designed so that those of you who get it right will reap the rewards by not having to re-work your code.

Version 1.0
The first iteration in the application is a proof-of-concept of configuring the pizza ordering system; many of the details will change, and more features will be added over the next few weeks.

In this version (1.0) you will develop a reference based object model; you will write a hierarchy of Test classes that main() uses to build the reference base object model and archive the data using Serialization. The model will setup and store the possible configurations that specify the options (and change in price) when deciding on the pizza order. Note that in Project 1.0, there will not be a way to specify the options for ordering a particular pizza, you are just setting up the possible options.

First you will build the underlying pizza model (think MVC) using normal Java classes, inner classes, and classic OOD. (This is a pattern called POJO)

For your proof of concept please consider the following requirements:

Build the options for a specifying a pizza that includes all the differrent possible settings for a pizza. What are the options for a pizza? We will refine this in class - make sure you follow what we decide. The purpose of your system is to allow websites or other UIs to be built using the API you are starting to design and code.

Your design must handle the following:

  1. A pizza has a base-price, which is for a small pizza with cheese.
  2. Size - S, M, L. The price for a small is the base price; a medium adds 2,000rwf to the base price, and a large adds 3,500rwf to the base price.
  3. Delivery mode - take-away, eat-in, or delivered. Delivery adds an extra charge of 1,000rwf.
  4. Meat choices - beef, pepperoni, anchovy, and ham, plus one more that you choose.
  5. Veg choices - mushroom, onion, black olives, pineapple, tomatoes, plus one more that you choose.
  6. Cheese choices - regular, no cheese or extra cheese.

Some ingredients add an extra cost, for instance pepperoni adds 800rwf to the base price of the pizza.

Your Deliverable: Design and code classes for these requirements and write a driver program to instantiate a number of Pizza configuration objects. You will write and read each one to/from a file using Serialization.

For testing, implement a hierarchy of Test classes that your main() uses instead of directly creating PizzaConfigs. You MUST use polymorphism in your main(). We will discuss this in class.

Plan of Attack

Learning Objectives:

Object Theory
Access Modes
Inner Classes
Interfaces
Serialization

Step 1 - Analysis

  1. Analyze data and create a set of classes.
  2.  From the data provided in project description you can try to find patterns in structuring information. You will notice that:

Step 2 - Designing Classes

  1. Using the information in the last step (Analysis) you can start designing classes and how each might relate.
  2. We will certainly not create classes for each property as that will not be reusable design. Note this is different that your first pizza class!
  3. We can create an PizzaConfig class that can hold the name of the base price and information about all the possible sets of options (let's call each one OptionSet).
  4. Each OptionSet has a name.
  5. Each OptionSet has a set of values. Each value can be defined in its own class (let's call it Option). Each Option has a name and price as properties.

Step 3 - Define Class relationships for the model package

  1. Following this design, we can see that PizzaConfig will contain OptionSets and each OptionSet will contain Options.
  2. For practice and learning purposes you must make the Option class an Inner class of OptionSet.
  3. The structure at a high level might look like this:
// This class will represent the Pizza Configuration
public class PizzaConfig
{
private String name;
private double basePrice;
private OptionSet options[]; // Note: Version 1.0 you MUST use a partially-filled array and handle all consequences

public PizzaConfig(String n, int maxOptionSets)
{
    // What should this method do? What other constructors are needed?
}
}

Note: end of PizzaConfig class, put OptionSet in its own src file

class OptionSet
{
private String name;
private Option choices[]; 

// what constructors should you write?
// make sure all methods are protected.
class Option
{
    private String name;
    private double price;
}
}

Step 4 - Planning detailed design of model package

For each class (PizzaConfig, OptionSet and Option) make sure you have applied the following criteria to ensure the class definition is complete and properly coded.
  1. Add constructors for every possible meaningful combination.
  2. Write get and set methods for each property. For example, since the OptionSet class has an Option array you should write get methods to get one or more Option values.

    Tip: Be careful; auto-generated code from IDEs will not suffice.

  3. For each property in a class make sure you have added operations for Creating (generally done with constructors), Reading (Generally done with read or find functions and/or getters), Updating (Update functions that will call find functions), Deleting values (Delete value of a property). These are called CRUD.
  4. As a result of the above work your PizzaConfig model class structure might look like this:
PizzaConfig class
Properties:
baseprice
OptionSet []
Constructors (create)
Method categories for all the above stated properties.
Getters (read)
Find (read)
Setters (Inserting values)
Update
Delete: deleting an Option (1 at a time) or an OptionSet (1 at a time).

5. A more detailed analysis on each category produces following possibilities for each category

PizzaConfig class
i. baseprice
ii. OptionSet opset []
Constructors
i. PizzaConfig()
ii. PizzaConfig(baseprice, OptionSetsize)
Getter
i. Write methods for following criteria:
1. Get Pizza Base Price
2. Get OptionSet (by index value)
Find
i. Find OptionSet with name
ii. Find Option with name (in context of OptionSet)
Setters
i. Set Base Price
ii. Set the values of an OptionSet
iii. Set the value of an Option (in context of an OptionSet)
Delete
i. Delete an Option in an OptionSet
ii. Delete an entire OptionSet
Update (Find and Set)
i. Update the values of OptionSet
ii. Update the value of an Option (in context of an OptionSet)

Step 5 - Constructing the model package

After all classes have been designed you can start doing construction. When designing and writing your code, factor in these elements:
  1. Add the PizzaConfig, OptionSet and Option classes in a package called model.
  2. Make sure you only have one class per java file, expect for inner classes (like Option).
  3. Make sure the methods in Option and OptionSet class are protected and properties are private. The Option and OptionSet classes should use the default access mode (as shown above).
  4. Methods in the PizzaConfig class should be public and the properties should be private.
  5. You should also follow these coding conventions:
    1. Each class should have grouping of elements as follows:
    2. a. instance variables
      b. static variables
      c. constructors
      d. getter/setters
      e. instance methods
      f. static methods
    3. All class names start with upper case letter.
    4. Every class should have a toString() method. Do not use String concatenation in the toString() method; instead, use StringBuffer or StringBuilder.
    5. Every class should be able to print its properties through a print() method.
    6. Do not use any static methods in the model package.
  6. Do not use ArrayList or any other Collections in this submission - an array is required for every list in your 1.0 implementation.

Step 6 - Learn Serialization and implement it (useful for testing)

  1. Once you have created your class, and built an instance of PizzaConfig class you should archive the instance using Serialization. To do this you will need to decide which classes should implement the Serializable interface.
  2. After the file has been written to disk be sure to read it back and print the properties to console.
  3. When working with serialization you should write one object per file. To write more than 1 object, you would use an array or a collection.
TIP - How to write and read a serialized file:

class A implements Serializable {...}
class B extends A {...}
class ObjectFileTest
{
public static void main(String[] args)
{
try
{
    A [] staff = new A[3];
    staff[0] = new A();
    staff[1] = new B();
    staff[2] = new A();

    ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("A.dat"));
    out.writeObject(staff);
    out.close();

    ObjectInputStream in = new ObjectInputStream(new FileInputStream("A.dat"));
    A[] newStaff = (A[]) in.readObject(); // Note: what is this line doing??
    in.close(); } catch(Exception e) { System.out.print("Error: " + e);

    System.exit(1);
}
}
}

Step 8 - Test and Submit

  1. Use the following class and algorithm for your test driver that tests your entire project.

    class TestDriver
    {
    public static void main(String [] args)
    {

    // Create and use multiple PizzaTest classes, demonstrates polymorphism
    PizzaTest pizzaTest;
    pizzaTest = new PizzaTest1();
    pizzaTest.executeTest();
    pizzaTest = new PizzaTest2();
    pizzaTest.executeTest();
    ...

    }
    }

    Use an interface for your testers. Each should

    // Create a pizza configuration
    // Print it
    pizzaConfig.print();
    // Serialize the object
    // Deserialize the object and read it into memory.
    // Print the read-in one.

  2. Turn in your submission using the criteria specified by your TA(s). Don't forget your build.xml file(s).
Submitting your work
Please review your work using the following Grading criteria;

Program Specification / Correctness
  • No errors, program always works correctly and meets the specification(s)
  • The code could be reused as a whole or each routine could be reused.
  • Classes are in separate packages. The model package has PizzaConfig, OptionSet and Option Class; the test package has your test classes.
  • Java coding conventions are followed.
  • PizzaConfig class should be complete, with methods for all CRUD operations for the Option, OptionSet and PizzaConfig classes.
  • The specified access modes are being used:
    1. All properties are private.
    2. There are no static variables (use local ones in main()).
    3. The Option and OptionSet classes should use the default access mode (as shown above).
    4. The methods in in Option and OptionSet class are protected.
  • Methods in the PizzaConfig class should be public and the properties should be private.
  • Serialization and Deserialization is demonstrated.
  • Collections like ArrayList are not used.
Readability
  • No errors, code is readable, and well-organized.
  • Code has been packaged and authored based on Java Coding Standards.
  • Code organized into functionally relevant packages e.g. exception, util, test, model, etc. in their own respective packages.
  • Documentation
    • The documentation of the code (commenting) is well written and clearly explains what the code is accomplishing.
    • Class Diagram for design is reviewed before coding.
    • Class Diagram of final code is provided.
    • Output from all test runs is provided - put this output in a file called PizzaConfigTest.txt. Make sure your test output is properly labelled.