This textbook was authored for the CIS 400 - Object-Oriented Design, Implementation, and Testing course at Kansas State University. This section describes assignments specific to the Spring 2023 offering of that course. Prior semester offerings can be found here. If you are not enrolled in the course, please disregard this section.
For this milestone, you will be creating new classes representing an order and refactoring your existing classes to implement an interface and base classes. You will also need to update your unit tests to account for these changes. Finally, you will also create a UML class diagram to represent your classes.
General requirements:
You need to follow the style laid out in the C# Coding Conventions
You need to document your code using XML-style comments, with a minimum of
<summary>
tags, plus<param>
,<returns>
, and<exception>
as appropriate.
Assignment requirements:
You will need to:
Create an
IMenuItem
interface to represent an item appearing on the menuRefactor your existing classes to implement the
IMenuItem
interfaceAdd additional unit tests to verify your menu items can be treated as
IMenuItem
instancesCreate an
Order
class to represent a collection of menu items being ordered togetherWrite unit tests to verify your new classes work as expected
Create a UML diagram for your
Data
Project
Purpose:
This milestone serves to introduce and utilize aspects of polymorphism including base classes, abstract base classes, abstract methods, virtual methods, method overriding, and interfaces. While the actual programming involved is straightforward, the concepts involved can be challenging to master. If you have any confusion after you have read the entire assignment please do not hesitate to reach out to a Professor Bean, the TAs, or your classmates over Discord.
IMenuItem Interface
You will create an interface named IMenuItem
in the file IMenuItem.cs to represent the properties that all menu items share, which should include:
- A get-only
Name
property of typestring
- A get-only
Description
property of typestring
- A get-only
Price
property of typedecimal
- A get-only
Calories
property of typeuint
- A get-only
SpecialInstructions
property of typeIEnumerable<string>
You will need to implement this interface on all existing and future menu items defined in the Data
project.
You will also want to test that your menu items can be cast to be an IMenuItem
using the Assert.IsAssignableFrom<T>()
assertion in the corresponding unit test file with a new Fact
.
Abstract Base Classes
You will also write abstract base classes representing Entree
, Side
, and Drink
menu items, in files named Entree.cs, Side.cs, and Drink.cs respectively. These should generalize (collect together) the properties that each of these categories of menu items have in common - either as abstract
or virtual
properties, to be overridden as needed in the derived classes.
All of your menu classes should be refactored to derive from one of these abstract base classes. Note that this may allow you to remove methods or require you to override
the base method.
You will also want to test that your menu items can be cast to be the corresponding base class using the Assert.IsAssignableFrom<T>()
assertion in the corresponding unit test file with a new Fact
.
Drink Classes
You will also need to implement new classes representing the drinks available at The Flying Saucer, which are Liquified Vegetation, Saucer Fuel, and Inorganic Substance. All drinks have a Size
property of type ServingSize
, in addition to the normal IMenuItem
properties.
Liquified Vegetation
Property | Accessors | Type | Value |
---|---|---|---|
Name | get only | string | "Liquified Vegetation" |
Description | get only | string | "A cold glass of blended vegetable juice." |
Size | get and set | ServingSize | Default of `ServingSize.Small` |
Ice | get and set | bool | Defaults to true |
Price | get only | decimal | $1.00 for small, $1.50 for medium, $2.00 for large |
Calories | get only | uint | 72 for small, 144 for medium, 216 for large |
SpecialInstructions | get only | IEnumerable〈string〉 | Should include:
|
Saucer Fuel
Property | Accessors | Type | Value |
---|---|---|---|
Name | get only | string | "Saucer Fuel" or "Decaf Saucer Fuel" if Decaf is true |
Description | get only | string | "A steaming cup of coffee." |
Size | get and set | ServingSize | Default of `ServingSize.Small` |
Decaf | get and set | bool | Defaults to false |
Cream | get and set | bool | Defaults to false |
Price | get only | decimal | $1.00 for small, $1.50 for medium, $2.00 for large |
Calories | get only | uint | 1 for small, 2 for medium, 3 for large, plus 29 calories for cream |
SpecialInstructions | get only | IEnumerable〈string〉 | Should include:
|
Inorganic Substance
Property | Accessors | Type | Value |
---|---|---|---|
Name | get only | string | "Inorganic Substance" |
Description | get only | string | "A cold glass of ice water." |
Size | get and set | ServingSize | Default of `ServingSize.Small` |
Ice | get and set | bool | Defaults to true |
Price | get only | decimal | $0.00 for any size |
Calories | get only | uint | 0 for all sizes |
SpecialInstructions | get only | IEnumerable〈string〉 | Should include:
|
Order Class
You will also need to create a class, Order
in a file Order.cs, representing an order containing multiple, potentially customized menu items. This class will need to implement the ICollection<IMenuItem>
interface, allowing it to be treated as a collection. In addition to the methods and properties required for the interface, it should have the additional properties of:
Subtotal
, a get-onlydecimal
that is the price of all items in the orderTaxRate
, a get/setdecimal
that represents the sales tax rateTax
, a get-onlydecimal
that is the tax for the order (Subtotal
*TaxRate
)Total
, a get-onlydecimal
that is the sum of theSubtotal
andTax
Add Tests
Remember that your new classes (Order
and all the drinks) will all need to have corresponding unit tests added to the DataTests
project. Abstract classes Entree
, Side
, and Drink
do not need to be tested, but any properties or methods inherited from them should be tested in the unit tests of the derived classes.
Note that for testing the Order
class, you will want to use a mock object rather than your real menu item classes. This can be declared in the unit test class like this:
/// <summary>
/// A mock menu item for testing
/// </summary>
internal MockMenuItem : IMenuItem
{
public string Name {get; set;}
public string Description {get; set;}
public decimal Price {get; set;}
public uint Calories {get; set;}
public IEnumerable<string> SpecialInstructions {get;set;}
}
This allows you to initialize it with known values in a test, i.e. we might initialize four menu items with prices to test the Subtotal
property:
[fact]
public SubtotalShouldReflectItemPrices()
{
Order order = new Order();
order.Add(new MockMenuItem() {Price = 1.00m});
order.Add(new MockMenuItem() {Price = 2.50m});
order.Add(new MockMenuItem() {Price = 3.00m});
Assert.Equal(6.50m, order.Subtotal);
}
UML Class Diagram
Finally, you will need to create a UML class diagram for the Data
project, and add it to your repository. This can be done with Visio or another visual editing program like Draw.io or Lucid Charts. You should save the diagram in a PDF or image format that the graders can view. You also will want to keep it in an editable format, as you’ll be updating it in future milestones. Be sure to follow the instructions in [Adding Documentation Files]https://textbooks.cs.ksu.edu/cis400/b-git-and-github/13-adding-documentation-files/ and double-check that the UML diagrams appear in your release.
Submitting the Assignment
Once your project is complete, merge your feature branch back into the main
branch and create a release tagged v0.4.0
with name "Milestone 4"
. Copy the URL for the release page and submit it to the Canvas assignment.
Grading Rubric
The grading rubric for this assignment will be:
20% Structure Did you implement the structure as laid out in the specification? Are the correct names used for classes, enums, properties, methods, events, etc? Do classes inherit from expected base classes?
20% Documentation Does every class, method, property, and field use the correct XML-style documentation? Does every XML comment tag contain explanatory text? Is there a UML Diagram for the data project? Does the UML accurately reflect the structure of the project
20% Design Are you appropriately using C# to create reasonably efficient, secure, and usable software? Does your code contain bugs that will cause issues at runtime?
20% Functionality Does the program do what the assignment asks? Do properties return the expected values? Do methods perform the expected actions?
20% Tests Does the test suite include unit tests for all classes? Do the unit tests provide adequate coverage of the project?
Projects that do not compile will receive an automatic grade of 0.