前言
源码 http://chenjinsui.com/oop_homework.zip
和上次作业相比,增加了类注释和方法注释(虽然大部分是从文档上copy下来的)。
需求分析
上次作业已经完成了Coffee
类、CoffeeBrewer
类、Product
类、OrderItem
类。这次作业要完成一个完整的卖咖啡系统。
UML图文档里面有,这里不贴了。
Catalog
类中使用ArrayList
保存了一组Product
,实现了产品目录的功能。Order
类中使用ArrayList
保存了一组OrderItem
,实现了订单的功能。Sales
类使用ArrayList
保存了一组Order
,实现了账目(maybe)的功能。GourmetCoffee
类使用了Order
类来保存当前订单,使用Catalog
类实现目录,使用Sales
类实现账单。(但我实在搞不懂所给程序为什么要在StdErr
中输出主菜单…)
文档中指出,上面列表种的前三个类都要实现Iterable接口来实现for-each循环。
Catalog类的实现
成员变量与构造器
products
的默认值直接写成new ArrayList<>()
构造器就没用了,但文档又让写构造器,也不能删,所以只能摆上一个空壳。
一个Catalog
对象中,products
的地址是永远不会改变的,所以加上一个final
。
private final ArrayList<Product> products = new ArrayList<>();
public Catalog() {}
但其实文档是想让我们这么写
private ArrayList<Product> products;
public Catalog() {
this.products = new ArrayList<>();
}
另外两个类都同理。
iterator()方法
为了实现Iterable
接口,要重写iterator()
方法。直接返回products
的迭代器即可。
/**
* @return an iterator over the instances in the collection products
*/
@Override
public Iterator<Product> iterator() {
return products.iterator();
}
另外两个类同理。
Order类的实现
getTotalCost()方法
每次调用这个方法都需要遍历一遍items
,浪费了很多时间。这个方法可以优化(但嫌麻烦,没改)。
可以在类中定义一个double
型的成员变量totalCost
。每次addItem
订单就给这个变量增加相应的值,每次removeItem
就给这个变量减去相应的值,getTotalCost()
方法中直接返回totalCost
值即可。
/**
* @return the total cost of the order.
*/
public double getTotalCost() {
double totalCost = 0;
for (var item : items)
totalCost += item.getValue();
return totalCost;
}
Sales类的实现
没什么可说的。
GourmetCoffee类的补全
主体都已经是写好的了,就剩下两个方法需要自己写。
输出不需要sout,可以直接用类中给的stdOut
读清题意,两个方法都很简单。
displayNumberOfOrders(Product product)方法
/**
* Displays the number of orders that contain a specified product
*
* @param product the <code>Product</code> object to be displayed.
*/
public void displayNumberOfOrders(Product product) {
int tot = 0;
for(var order : sales){
for(var item : order){
if(item.getProduct().equals(product)){
tot++;
break;
}
}
}
stdOut.println(tot);
}
displayTotalQuantityOfProducts()方法
优化:可以将product
与其出现的数量形成映射。进行遍历时,每找到一个product
,其对应的映射值加1。等遍历结束后,遍历输出所以映射即可。时间复杂度降了非常多。但由于初学,不知道怎么用Java实现,所以没进行优化。
/**
* Displays the total quantity of product that have has sold for each
* product in the catalog.
*/
public void displayTotalQuantityOfProducts() {
for (var product : catalog) {
int tot = 0;
for (var order : sales) {
for (var item : order) {
if (item.getProduct().equals(product))
tot += item.getQuantity();
}
}
stdOut.println(product.getCode() + " " + tot);
}
}