【Java】设计模式在Gourmet咖啡系统中的应用
下載鏈接
Download
前塵往事
面向對象設計、UML建模與基本的Java面向對象編程實現
后續篇章
實驗二:異常和IO在Gourmet咖啡系統中的應用
Using Design Patterns in the Gourmet Coffee System
Prerequisites, Goals, and Outcomes
Prerequisites: Before you begin this exercise, you need mastery of the following:
- Object-oriented Programming
- How to define interfaces
- How to implement interfaces
- Design Patterns:
- Knowledge of the singleton pattern
- Knowledge of the strategy pattern
Goals: Reinforce your ability to use the singleton and strategy patterns
Outcomes: You will demonstrate mastery in the following:
- Producing applications that use the singleton pattern
- Producing applications that use the strategy pattern
Background
In this assignment, you will create another version of the Gourmet Coffee System. This version will present the user with four choices:
The user will be able to display the sales information in three formats: plain text, HTML, or XML. Part of the work has been done for you and is provided in the student archive. You will implement the code that formats the sales information. This code will use the singleton and strategy patterns.
Description
The following class diagram shows how the singleton and strategy pattern will be used in your implementation:
Figure 1 Portion of Gourmet Coffee System class diagram
- Interface SalesFormatter declares a method called formatSales that produces a string representation of the sales information.
- Class PlainTextSalesFormatter implements formatSales. Its version returns the sales information in a plain-text format.
- Class HTMLSalesFormatter implements formatSales. Its version returns the sales information in an HTML format.
- Class XMLSalesFormatter implements formatSales. Its version returns the sales information in an XML format.
- Class GourmetCoffee is the context class. It also contains client code. The client code calls:
- Method GourmetCoffee.setSalesFormatter to change the current formatter
- Method GourmetCoffee.displaySales to display the sales information using the current formatter
In this assignment, you should implement the following interface and classes:
- SalesFormatter
- PlainTextSalesFormatter
- HTMLSalesFormatter
- XMLSalesFormatter
- GourmetCoffee (a partial implementation is provided in the student archive)
Complete implementations of the following classes are provided in the student archive:
- Coffee
- CoffeeBrewer
- Product
- Catalog
- OrderItem
- Order
- Sales
Interface SalesFormatter
Interface SalesFormatter declares the method that every “Formatter” class will implement.
Method:
- public String formatSales(Sales sales): Produces a string representation of the sales information.
Class PlainTextSalesFormatter
Class PlainTextSalesFormatter implements the interface SalesFormatter. This class is implemented as a singleton so a new object will not be created every time the plain-text format is used.
Static variable:
- singletonInstance: The single instance of class PlainTextSalesFormatter.
Constructor and methods:
- static public PlainTextSalesFormatter getSingletonInstance(): Static method that obtains the single instance of class PlainTextsalesFormatter.
- private PlainTextSalesFormatter(): Constructor that is declared private so it is inaccessible to other classes. A private constructor makes it impossible for any other class to create an instance of class PlainTextSalesFormatter.
- public String formatSales(Sales sales): Produces a string that contains the specified sales information in a plain-text format. Each order in the sales information has the following format:
where
- number is the order number.
- quantityX is the quantity of the product.
- codeX is the code of the product.
- priceX is the price of the product.
- totalCost is the total cost of the order.
Each order should begin with a dashed line. The first order in the sales information should be given an order number of 1, the second should be given an order number of 2, and so on.
Class HTMLSalesFormatter
Class HTMLSalesFormatter implements the interface SalesFormatter. This class is implemented as a singleton so a new object will not be created every time the HTML format is used.
Static variable:
- singletonInstance: The single instance of class HTMLSalesFormatter.
Constructor and methods:
- static public HTMLSalesFormatter getSingletonInstance(): Static method that obtains the single instance of class HTMLSalesFormatter.
- private HTMLSalesFormatter(): Constructor that is declared private so it is inaccessible to other classes. A private constructor makes it impossible for any other class to create an instance of class HTMLSalesFormatter.
- public String formatSales(Sales sales): Produces a string that contains the specified sales information in an HTML format.
The string should begin with the following HTML:
<html> <body> <center><h2>Orders</h2></center>Each order in the sales information should begin with horizontal line, that is, an <hr> tag.
Each order in the sales information should have the following format:
<hr> <h4>Total = totalCost</h4> <p> <b>code:</b>code1<br> <b>quantity:</b>quantity1<br> <b>price:</b>price1 </p>... <p> <b>code:</b>codeN<br> <b>quantity:</b>quantityN<br> <b>price:</b>priceN </p>where:
- quantityX is the quantity of the product.
- codeX is the code of the product.
- priceX is the price of the product.
- totalCost is the total cost of the order.
The string should end with the following HTML:
</body> </html>Class XMLSalesFormatter
Class XMLSalesFormatter implements the interface SalesFormatter. This class is implemented as a singleton so a new object will not be created every time the XML format is used.
Static variable:
- singletonInstance: The single instance of class XMLSalesFormatter.
Constructor and methods:
- static public XMLSalesFormatter getSingletonInstance(): Static method that obtains the single instance of class XMLSalesFormatter.
- private XMLSalesFormatter(): Constructor that is declared private so it is inaccessible to other classes. A private constructor makes it impossible for any other class to create an instance of class XMLSalesFormatter.
- public String formatSales(Sales sales): Produces a string that contains the specified sales information in an XML format.
The string should begin with the following XML:
<Sales>Each order in the sales information should have the following format:
<Order total="totalCost"> <OrderItem quantity="quantity1" price="price1">code1</OrderItem>... <OrderItem quantity="quantityN" price="priceN">codeN</OrderItem> </Order>where:
- quantityX is the quantity of the product.
- codeX is the code of the product.
- priceX is the price of the product.
- totalCost is the total cost of the order.
The string should end with the following XML:
</Sales>Class GourmetCoffee
Class GourmetCoffee lets the user display the sales information in one of three formats: plain text, HTML, or XML. A partial implementation of this class is provided in the student archive.
Instance variables:
- private Sales sales: A list of the orders that have been paid for.
- private SalesFormatter salesFormatter: A reference variable that refers to the current formatter: a PlainTextSalesFormatter, HTMLSalesFormatter, or XMLSalesFormatter object.
Constructor and methods:
The following methods and constructor are complete and require no modification:
- public static void main(String[] args) throws IOException: Starts the application.
- private GourmetCoffee(): Initialize instance variables sales and salesFormatter.
- private Catalog loadCatalog(): Populates the product catalog.
- private void loadSales(Catalog catalog): Populates the sales object.
- private int getChoice() throws IOException: Displays a menu of options and verifies the user’s choice.
The following methods should be completed:
- private void setSalesFormatter(SalesFormatter newFormatter): Changes the current formatter by updating the instance variable salesFormatter with the object specified in the parameter newFormatter.
- private void displaySales(): Displays the sales information in the standard output using the method salesFormatter.formatSales to obtain the sales information in the current format.
- private void run() throws IOException: Presents the user with a menu of options and executes the selected task
- If the user chooses option 1, run calls method setSalesFormatter with the singleton instance of class PlainTextSalesFormatter, and calls method displaySales to display the sales information in the standard output.
- If the user chooses option 2, run calls method setSalesFormatter with the singleton instance of class HTMLSalesFormatter, and calls method displaySales to display the sales information in the standard output.
- If the user chooses option 3, run calls method setSalesFormatter with the singleton instance of class XMLTextSalesFormatter, and calls method displaySales to display the sales information in the standard output.
Files
The following files are needed to complete this assignment:
- student-files.zip — Download this file. This archive contains the following:
- Class files
- Coffee.class
- CoffeeBrewer.class
- Product.class
- Catalog.class
- OrderItem.class
- Order.class
- Sales.class
- Documentation
- Coffee.html
- CoffeeBrewer.html
- Product.html
- Catalog.html
- OrderItem.html
- Order.html
- Sales.html
- GourmetCoffee.java. A partial implementation of the class GourmetCoffee.
Tasks
Implement the interface SalesFormatter and the classes PlainTextSalesFormatter, HTMLSalesFormatter, XMLSalesFormatter. Finish the implementation of class GourmetCoffee. Document using Javadoc and follow Sun’s code conventions. The following steps will guide you through this assignment. Work incrementally and test each increment. Save often.
C:>unzip student-files.zip
- If the user chooses to display the sales information in plain text, the output should be:
- If the user chooses to display the sales information in HTML, the output should be:
- If the user chooses to display the sales information in XML, the output should be:
Submission
Upon completion, submit only the following:
提供的.class文件
這真是不可描述。。。
下面的代碼是逆向工程←_←反編譯得到的.java,eclipse裝插件、idea自身都可以支持簡單不加密的逆向工程。
反編譯出來的還是比較low的,比如泛型啥的都沒有啊!
Product類
public class Product {private String code;private String description;private double price;public Product(String var1, String var2, double var3) {this.code = var1;this.description = var2;this.price = var3;}public String getCode() {return this.code;}public String getDescription() {return this.description;}public double getPrice() {return this.price;}public boolean equals(Object var1) {return var1 instanceof Product && this.getCode().equals(((Product)var1).getCode());}public String toString() {return this.getCode() + "_" + this.getDescription() + "_" + this.getPrice();} }Coffee類
public class Coffee extends Product {private String origin;private String roast;private String flavor;private String aroma;private String acidity;private String body;public Coffee(String var1, String var2, double var3, String var5, String var6, String var7, String var8, String var9, String var10) {super(var1, var2, var3);this.origin = var5;this.roast = var6;this.flavor = var7;this.aroma = var8;this.acidity = var9;this.body = var10;}public String getOrigin() {return this.origin;}public String getRoast() {return this.roast;}public String getFlavor() {return this.flavor;}public String getAroma() {return this.aroma;}public String getAcidity() {return this.acidity;}public String getBody() {return this.body;}public String toString() {return super.toString() + "_" + this.getOrigin() + "_" + this.getRoast() + "_" + this.getFlavor() + "_" + this.getAroma() + "_" + this.getAcidity() + "_" + this.getBody();} }CoffeeBrewer類
public class CoffeeBrewer extends Product {private String model;private String waterSupply;private int numberOfCups;public CoffeeBrewer(String var1, String var2, double var3, String var5, String var6, int var7) {super(var1, var2, var3);this.model = var5;this.waterSupply = var6;this.numberOfCups = var7;}public String getModel() {return this.model;}public String getWaterSupply() {return this.waterSupply;}public int getNumberOfCups() {return this.numberOfCups;}public String toString() {return super.toString() + "_" + this.getModel() + "_" + this.getWaterSupply() + "_" + this.getNumberOfCups();} }OrderItem類
public class OrderItem {private Product product;private int quantity;public OrderItem(Product var1, int var2) {this.product = var1;this.quantity = var2;}public Product getProduct() {return this.product;}public int getQuantity() {return this.quantity;}public void setQuantity(int var1) {this.quantity = var1;}public double getValue() {return this.getProduct().getPrice() * (double)this.getQuantity();}public String toString() {return this.getQuantity() + " " + this.getProduct().getCode() + " " + this.getProduct().getPrice();} }Order類
import java.util.ArrayList; import java.util.Iterator;public class Order implements Iterable<OrderItem> {private ArrayList<OrderItem> items = new ArrayList<>();public Order() {}public void addItem(OrderItem var1) {this.items.add(var1);}public void removeItem(OrderItem var1) {this.items.remove(var1);}public Iterator<OrderItem> iterator() {return this.items.iterator();}public OrderItem getItem(Product var1) {Iterator var2 = this.items.iterator();OrderItem var3;do {if (!var2.hasNext()) {return null;}var3 = (OrderItem)var2.next();} while(!var3.getProduct().equals(var1));return var3;}public int getNumberOfItems() {return this.items.size();}public double getTotalCost() {double var1 = 0.0D;OrderItem var4;for(Iterator var3 = this.items.iterator(); var3.hasNext(); var1 += var4.getValue()) {var4 = (OrderItem)var3.next();}return var1;} }Catalog類
import java.util.ArrayList; import java.util.Iterator;public class Catalog implements Iterable<Product> {private ArrayList<Product> products = new ArrayList<>();public Catalog() {}public void addProduct(Product var1) {this.products.add(var1);}public Iterator<Product> iterator() {return this.products.iterator();}public Product getProduct(String var1) {Iterator var2 = this.products.iterator();Product var3;do {if (!var2.hasNext()) {return null;}var3 = (Product)var2.next();} while(!var3.getCode().equals(var1));return var3;}public int getNumberOfProducts() {return this.products.size();} }Sales類
import java.util.ArrayList; import java.util.Iterator;public class Sales implements Iterable<Order> {private ArrayList<Order> orders = new ArrayList<>();public Sales() {}public void addOrder(Order var1) {this.orders.add(var1);}public Iterator<Order> iterator() {return this.orders.iterator();}public int getNumberOfOrders() {return this.orders.size();} }Code
SalesFormatter類
public interface SalesFormatter {//Produces a string representation of the sales information.public abstract String formatSales(Sales sales);}PlainTextSalesFormatter類
import java.util.Iterator;public class PlainTextSalesFormatter implements SalesFormatter {private static PlainTextSalesFormatter singletonInstance; private PlainTextSalesFormatter() { } public static synchronized PlainTextSalesFormatter getSingletonInstance() { if (singletonInstance == null) singletonInstance = new PlainTextSalesFormatter(); return singletonInstance; } public String formatSales(Sales sales) { String string = ""; int i = 1;Iterator<Order> iterator1 = sales.iterator();while(iterator1.hasNext()) {Order order = iterator1.next();string +="---------------------\r\n"; string += "Order " + i + "\r\n\r\n"; Iterator<OrderItem> iterator2 = order.iterator();while(iterator2.hasNext()) {OrderItem orderItem = iterator2.next();string += orderItem.getQuantity() + " " + orderItem.getProduct().getCode() + " " +orderItem.getProduct().getPrice() + "\r\n";}i++; string += "\r\n" + "Total = " + order.getTotalCost() + "\r\n"; } return string; } }HTMLSalesFormatter類
import java.util.Iterator;public class HTMLSalesFormatter implements SalesFormatter {private static HTMLSalesFormatter singletonInstance; private HTMLSalesFormatter() { } public static synchronized HTMLSalesFormatter getSingletonInstance() { if (singletonInstance == null) singletonInstance = new HTMLSalesFormatter(); return singletonInstance; } public String formatSales(Sales sales) { String string = ""; string +="<html>\r\n <body>\r\n <center><h2>Orders</h2></center>\r\n";Iterator<Order> iterator1 = sales.iterator();while(iterator1.hasNext()) {Order order = iterator1.next();string += " <hr>\r\n <h4>Total = " + order.getTotalCost() + "</h4>\r\n <p>\r\n"; Iterator<OrderItem> iterator2 = order.iterator();while(iterator2.hasNext()) {OrderItem orderItem = iterator2.next();string += " <b>code:</b> "+orderItem.getProduct().getCode()+"<br>\r\n" + " <b>quantity:</b> "+orderItem.getQuantity()+"<br>\r\n"+" <b>price:</b> "+orderItem.getProduct().getPrice()+"\r\n";} string += " </p>\r\n";} string += " </body>\r\n</html>\r\n";return string; }}XMLSalesFormatter類
import java.util.Iterator;public class XMLSalesFormatter implements SalesFormatter {private static XMLSalesFormatter singletonInstance; private XMLSalesFormatter() { } public static synchronized XMLSalesFormatter getSingletonInstance() { if (singletonInstance == null) singletonInstance = new XMLSalesFormatter(); return singletonInstance; } public String formatSales(Sales sales) { String string = ""; string +="<Sales>\r\n"; Iterator<Order> iterator1 = sales.iterator();while(iterator1.hasNext()) {Order order = iterator1.next();string += " <Order total=\""+order.getTotalCost()+"\">\r\n"; Iterator<OrderItem> iterator2 = order.iterator();while(iterator2.hasNext()) {OrderItem orderItem = iterator2.next();string += " <OrderItem quantity=\""+orderItem.getQuantity()+"\" price=\""+orderItem.getProduct().getPrice()+"\">"+orderItem.getProduct().getCode()+"</OrderItem>\r\n";} string += " </Order>\r\n";} string += "</Sales>\r\n";return string; } }GourmetCoffee類
import java.io.*; import java.util.*; import java.text.*;/*** This class implements a gourmet coffee system.** @author BlankSpace* @version 1.1.0* @see Product* @see Coffee* @see CoffeeBrewer* @see Catalog* @see OrderItem* @see Order* @see SalesFormatter* @see PlainTextSalesFormatter* @see HTMLSalesFormatter* @see XMLSalesFormatter*/ public class GourmetCoffee {private static BufferedReader stdIn =new BufferedReader(new InputStreamReader(System.in));private static PrintWriter stdOut = new PrintWriter(System.out, true);private static PrintWriter stdErr = new PrintWriter(System.err, true);private Sales sales;private SalesFormatter salesFormatter;/*** Loads data into the catalog and starts the application.** @param args String arguments. Not used.* @throws IOException if there are errors in the input.*/public static void main(String[] args) throws IOException {GourmetCoffee application = new GourmetCoffee();application.run();}/*** Constructs a <code>GourmetCoffee</code> object and* initializes the catalog and sales data.** @param initialCatalog a product catalog*/private GourmetCoffee() {this.sales = new Sales();this.salesFormatter = PlainTextSalesFormatter.getSingletonInstance();loadSales(loadCatalog());}/*** Creates an empty catalog and then add products to it.** @return a product catalog*/private Catalog loadCatalog() {Catalog catalog = new Catalog();catalog.addProduct(new Coffee("C001", "Colombia, Whole, 1 lb", 17.99,"Colombia", "Medium", "Rich and Hearty", "Rich","Medium", "Full"));catalog.addProduct(new Coffee("C002", "Colombia, Ground, 1 lb", 18.75,"Colombia", "Medium", "Rich and Hearty", "Rich","Medium","Full"));catalog.addProduct(new Coffee("C003", "Italian Roasts, Whole, 1 lb",16.80, "Latin American Blend", "Italian Roast","Dark and heavy", "Intense", "Low", "Medium"));catalog.addProduct(new Coffee("C004", "Italian Roasts, Ground, 1 lb",17.55, "Latin American Blend", "Italian Roast","Dark and heavy", "Intense", "Low", "Medium"));catalog.addProduct(new Coffee("C005", "French Roasts, Whole, 1 lb",16.80, "Latin American Blend", "French Roast","Bittersweet, full intense", "Intense, full", "None", "Medium"));catalog.addProduct(new Coffee("C006", "French Roasts, Ground, 1 lb",17.55, "Latin American Blend", "French Roast","Bittersweet, full intense", "Intense, full", "None", "Medium"));catalog.addProduct(new Coffee("C007", "Guatemala, Ground, 1 lb", 17.99,"Guatemala", "Medium", "Rich and complex", "Spicy","Medium to high", "Medium to full"));catalog.addProduct(new Coffee("C008", "Guatemala, Ground, 1 lb", 18.75,"Guatemala", "Medium", "Rich and complex", "Spicy","Medium to high", "Medium to full"));catalog.addProduct(new Coffee("C009", "Guatemala, Whole, 1 lb", 19.99,"Sumatra", "Medium", "Vibrant and powdery","Like dark chocolate", "Gentle", "Rich and full"));catalog.addProduct(new Coffee("C010", "Guatemala, Ground, 1 lb", 20.50,"Sumatra", "Medium", "Vibrant and powdery","Like dark chocolate", "Gentle", "Rich and full"));catalog.addProduct(new Coffee("C011", "Special Blend, Whole, 1 lb",16.80, "Latin American Blend", "Dark roast","Full, roasted flavor", "Hearty", "Bold and rich", "Full"));catalog.addProduct(new Coffee("C012", "Special Blend, Ground, 1 lb",17.55, "Latin American Blend", "Dark roast","Full, roasted flavor", "Hearty", "Bold and rich", "Full"));catalog.addProduct(new CoffeeBrewer("B001", "Home Coffee Brewer",150.00, "Brewer 100", "Pourover", 6));catalog.addProduct(new CoffeeBrewer("B002", "Coffee Brewer, 2 Warmers",200.00, "Brewer 200", "Pourover", 12));catalog.addProduct(new CoffeeBrewer("B003", "Coffee Brewer, 3 Warmers",280.00, "Brewer 210", "Pourover", 12));catalog.addProduct(new CoffeeBrewer("B004", "Commercial Brewer, 20 cups",380.00, "Quick Coffee 100", "Automatic", 20));catalog.addProduct(new CoffeeBrewer("B005", "Commercial Brewer, 40 cups",480.00, "Quick Coffee 200", "Automatic", 40));catalog.addProduct(new Product("A001", "Almond Flavored Syrup", 9.00));catalog.addProduct(new Product("A002", "Irish Creme Flavored Syrup", 9.00));catalog.addProduct(new Product("A003", "Mint Flavored syrup", 9.00));catalog.addProduct(new Product("A004", "Caramel Flavored Syrup", 9.00));catalog.addProduct(new Product("A005", "Gourmet Coffee Cookies", 12.00));catalog.addProduct(new Product("A006", "Gourmet Coffee Travel Thermo", 18.00));catalog.addProduct(new Product("A007", "Gourmet Coffee Ceramic Mug", 8.00));catalog.addProduct(new Product("A008", "Gourmet Coffee 12 Filters", 15.00));catalog.addProduct(new Product("A009", "Gourmet Coffee 36 Filters", 45.00));return catalog;}/*** Initializes the sales object.*/private void loadSales(Catalog catalog) {Order orderOne = new Order();orderOne.addItem(new OrderItem(catalog.getProduct("C001"), 5));this.sales.addOrder(orderOne);Order orderTwo = new Order();orderTwo.addItem(new OrderItem(catalog.getProduct("C002"), 2));orderTwo.addItem(new OrderItem(catalog.getProduct("A001"), 2));this.sales.addOrder(orderTwo);Order orderThree = new Order();orderThree.addItem(new OrderItem(catalog.getProduct("B002"), 1));this.sales.addOrder(orderThree);}/*** Displays a menu of options and verifies the user's choice.** @return an integer in the range [0,3]*/private int getChoice() throws IOException {int input;do {try {stdErr.println();stdErr.print("[0] Quit\n"+ "[1] Display sales (Plain Text)\n"+ "[2] Display sales (HTML)\n"+ "[3] Display sales (XML)\n"+ "choice> ");stdErr.flush();input = Integer.parseInt(stdIn.readLine());stdErr.println();if (0 <= input && 3 >= input) {break;} else {stdErr.println("Invalid choice: " + input);}} catch (NumberFormatException nfe) {stdErr.println(nfe);}} while (true);return input;}/*** Changes the sales .** @param newFormatter a sales formatter*/private void setSalesFormatter(SalesFormatter newFormatter){if (newFormatter instanceof PlainTextSalesFormatter) {this.salesFormatter = newFormatter;} else if (newFormatter instanceof HTMLSalesFormatter) {this.salesFormatter = newFormatter;} else if (newFormatter instanceof XMLSalesFormatter) {this.salesFormatter = newFormatter;}/* PLACE YOUR CODE HERE */}/*** Displays the sales information in the current format.*/private void displaySales() {int size = this.sales.getNumberOfOrders(); if (size == 0) { stdErr.println("The catalog is empty"); } else { stdOut.println(salesFormatter.formatSales(sales)); } /* PLACE YOUR CODE HERE */}/*** Presents the user with a menu of options and executes the* selected task.*/private void run() throws IOException {int choice = getChoice();while (choice != 0) {if (choice == 1) {setSalesFormatter(PlainTextSalesFormatter.getSingletonInstance());displaySales();/* PLACE YOUR CODE HERE */} else if (choice == 2) {setSalesFormatter(HTMLSalesFormatter.getSingletonInstance());displaySales();/* PLACE YOUR CODE HERE */} else if (choice == 3) {setSalesFormatter(XMLSalesFormatter.getSingletonInstance());displaySales();/* PLACE YOUR CODE HERE */}choice = getChoice();}} } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的【Java】设计模式在Gourmet咖啡系统中的应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 队列模拟约瑟夫问题(洛谷P1996题题解
- 下一篇: 【Java】时间的新旧比较