The invoice-printing system program has a flaw - it mixes \"application logic\"
ID: 3873655 • Letter: T
Question
The invoice-printing system program has a flaw - it mixes "application logic" (the computation of total charges) and presentation (the visual appearance of the invoice) . Reimplement the program, using a separate InvoiceFormatter class to format the invoice. That is, the Invoice and LineItem methods are no longer responsible for formatting. However, they will acquire other responsibilities (Please comment the new responsibilites they got), because the InvoiceFormatter class needs to query them for the values that it requires.
/**
This program demonstrates the invoice classes by printing
a sample invoice.
*/
public class InvoicePrinter
{
public static void main(String[] args)
{
Address samsAddress
= new Address("Sam's Small Appliances",
"100 Main Street", "Anytown", "CA", "98765");
Invoice samsInvoice = new Invoice(samsAddress);
samsInvoice.add(new Product("Toaster", 29.95), 3);
samsInvoice.add(new Product("Hair dryer", 24.95), 1);
samsInvoice.add(new Product("Car vacuum", 19.99), 2);
System.out.println(samsInvoice.format());
}
}
////////////////////////////////////////////////////////////////////////////////////////////
/**
Describes a mailing address.
*/
public class Address
{
private String name;
private String street;
private String city;
private String state;
private String zip;
/**
Constructs a mailing address.
@param aName the recipient name
@param aStreet the street
@param aCity the city
@param aState the two-letter state code
@param aZip the ZIP postal code
*/
public Address(String aName, String aStreet,
String aCity, String aState, String aZip)
{
name = aName;
street = aStreet;
city = aCity;
state = aState;
zip = aZip;
}
/**
Formats the address.
@return the address as a string with three lines
*/
public String format()
{
return name + " " + street + " "
+ city + ", " + state + " " + zip;
}
}
////////////////////////////////////////////////////////////////////////////////////////////
import java.util.ArrayList;
/**
Describes an invoice for a set of purchased products.
*/
public class Invoice
{
private Address billingAddress;
private ArrayList<LineItem> items;
/**
Constructs an invoice.
@param anAddress the billing address
*/
public Invoice(Address anAddress)
{
items = new ArrayList<LineItem>();
billingAddress = anAddress;
}
/**
Adds a charge for a product to this invoice.
@param aProduct the product that the customer ordered
@param quantity the quantity of the product
*/
public void add(Product aProduct, int quantity)
{
LineItem anItem = new LineItem(aProduct, quantity);
items.add(anItem);
}
/**
Formats the invoice.
@return the formatted invoice
*/
public String format()
{
String r = " I N V O I C E "
+ billingAddress.format()
+ String.format(" %-30s%8s%5s%8s ",
"Description", "Price", "Qty", "Total");
for (LineItem item : items)
{
r = r + item.format() + " ";
}
r = r + String.format(" AMOUNT DUE: $%8.2f", getAmountDue());
return r;
}
/**
Computes the total amount due.
@return the amount due
*/
private double getAmountDue()
{
double amountDue = 0;
for (LineItem item : items)
{
amountDue = amountDue + item.getTotalPrice();
}
return amountDue;
}
}
////////////////////////////////////////////////////////////////////////////////////////////
/**
Describes a quantity of an article to purchase.
*/
public class LineItem
{
private int quantity;
private Product theProduct;
/**
Constructs an item from the product and quantity.
@param aProduct the product
@param aQuantity the item quantity
*/
public LineItem(Product aProduct, int aQuantity)
{
theProduct = aProduct;
quantity = aQuantity;
}
/**
Computes the total cost of this line item.
@return the total price
*/
public double getTotalPrice()
{
return theProduct.getPrice() * quantity;
}
/**
Formats this item.
@return a formatted string of this item
*/
public String format()
{
return String.format("%-30s%8.2f%5d%8.2f",
theProduct.getDescription(), theProduct.getPrice(),
quantity, getTotalPrice());
}
}
////////////////////////////////////////////////////////////////////////////////////////////
/**
Describes a product with a description and a price.
*/
public class Product
{
private String description;
private double price;
/**
Constructs a product from a description and a price.
@param aDescription the product description
@param aPrice the product price
*/
public Product(String aDescription, double aPrice)
{
description = aDescription;
price = aPrice;
}
/**
Gets the product description.
@return the description
*/
public String getDescription()
{
return description;
}
/**
Gets the product price.
@return the unit price
*/
public double getPrice()
{
return price;
}
}
Explanation / Answer
Please follow the code and comments for description :
CODE:
a) InvoiceFormatter.java:
/**
This is an interface describes the tasks that an invoice
formatter needs to carry out.
*/
public interface InvoiceFormatter
{
/**
Formats the header of the invoice.
@return the invoice header
*/
String formatHeader();
/**
Formats a line item of the invoice.
@return the formatted line item
*/
String formatLineItem(LineItem item);
/**
Formats the footer of the invoice.
@return the invoice footer
*/
String formatFooter();
}
b) SimpleFormatter.java:
/**
A simple invoice formatter.
*/
public class SimpleFormatter implements InvoiceFormatter
{
public String formatHeader()
{
total = 0;
return " I N V O I C E ";
}
public String formatLineItem(LineItem item)
{
total += item.getPrice();
return item.toString() + ": $"
+ item.getPrice() + " ";
}
public String formatFooter()
{
return " AMOUNT DUE: $%8.2f" + getAmountDue() + " ";
}
private double total;
}
c) LineItem.java:
/**
A line item in an invoice.
*/
public interface LineItem
{
/**
Gets the price of this line item.
@return the price
*/
double getPrice();
/**
Gets the description of this line item.
@return the description
*/
String toString();
}
d) Product.java:
/**
A product with a price and description.
*/
public class Product implements LineItem
{
/**
Constructs a product.
@param description the description
@param price the price
*/
public Product(String description, double price)
{
this.description = description;
this.price = price;
}
public double getPrice() { return price; }
public String toString() { return description; }
private String description;
private double price;
}
Hope this is helpful.
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.