The invoice-printing program has an unfortunate flaw—it mixes “application logic”, the computation of total charges, and “presentation”, the visual appearance of the invoice. To appreciate this flaw, imagine the changes that would be necessary to draw the invoice in HTML for presentation on the Web. 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, because the InvoiceFormatter class needs to query them for the values that it requires.

Complete the following files:

Address.java

Invoice.java

InvoiceFormatter.java

LineItem.java

Use the following files:

InvoicePrinter.java

/**
   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);

      InvoiceFormatter formatter = new InvoiceFormatter(samsInvoice);
      System.out.println(formatter.format());
   }
}

Product.java

/**
   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;
   }
}