沒想到從完賽後荒廢了這麼久XD
想說再往下一章看之前 先複習一下前面的觀念
順便實作上篇提到的迪米特法則看看⋯⋯
假設今天要設計一個簡單的超市結帳系統
會需要類別 Item
, Receipt
, Payment
首先是Item (商品)
非常直觀的包含商品價格與名稱
public class Item {
public String name;
public int price;
public Item(String name, int price){
this.name = name;
this.price = price;
}
}
付款方式的話 我希望有刷卡跟付現兩種選項
所以先定義一個抽象類別
public abstract class Payment {
protected String info;
public String getPaymentInfo(){
return this.info;
}
}
用到前面策略模式的概念
把不同實作邏輯封裝在類別 Cash
, Card
中
public class Cash extends Payment{
// 實際支付金額
public int paidPayment;
// 找回的金額
public int change;
public Cash(int paidPayment, int cost){
this.paidPayment = paidPayment;
change = paidPayment - cost;
this.info = "\nPayment: Cash";
this.info += "\nPaid: $" + paidPayment;
this.info += "\nReturn $" + change;
}
}
public class Card extends Payment{
public String bank;
protected String number;
protected String csc;
public Card(String bank, String number, String csc){
this.bank = bank;
this.number = number;
this.csc = csc;
int len = this.number.length();
String fourDigits = this.number.substring(len - 4, len);
this.info = "\nPayment: Card";
this.info += "\nCard number (last 4 digits): " + fourDigits;
}
}
最後是結帳的流程
public class Checkout {
protected int total;
public Receipt receipt;
protected Payment payment;
public ArrayList<Item> cart;
public int getTotal(ArrayList<Item> items){
for(int i = 0; i < items.size(); i++){
this.total += items.get(i).price;
}
return total;
}
public static void main(String args[]){
Checkout checkout = new Checkout();
checkout.cart = new ArrayList<Item>();
Item oranges = new Item("Heirloom Navel Oranges", 125);
Item frozenFries = new Item("McCain Extra Crispy Classic Fries", 399);
Item milk = new Item("Shamrock Farms Vitamin D Whole Milk", 169);
Item rib = new Item("Barbecue Sauce & 6 Boneless Rib-Shaped Patties", 1499);
Item toner = new Item("Garnier SKINACTIVE Micellar Cleansing Water", 125);
Item oatMeal = new Item("Organic Apple Cinnamon Instant Oatmeal Packets", 99);
checkout.cart.add(oranges);
checkout.cart.add(frozenFries);
checkout.cart.add(milk);
checkout.cart.add(rib);
checkout.cart.add(toner);
checkout.cart.add(oatMeal);
int total = checkout.getTotal(checkout.cart);
checkout.payment = new Cash(4200, total);
if(checkout.payment != null){
Receipt receipt = new Receipt(checkout.cart, total, checkout.payment.getPaymentInfo());
receipt.eReceipt = true;
receipt.showContent();
}
else{
System.out.println("You haven't pay the bill.");
}
}
}
輸出如下:
===== RECEIPT =====
Items:
Heirloom Navel Oranges $125
McCain Extra Crispy Classic Fries $399
Shamrock Farms Vitamin D Whole Milk $169
Barbecue Sauce & 6 Boneless Rib-Shaped Patties $1499
Garnier SKINACTIVE Micellar Cleansing Water $125
Organic Apple Cinnamon Instant Oatmeal Packets $99
Total: 2416
Payment: Cash
Paid: $4200
Return $1784
Check more info online.
後來我發現 我也有個地方不小心違反了狄米特原則
在結帳過程的
Receipt receipt = new Receipt(checkout.cart, total, checkout.payment.getPaymentInfo());
類別Receipt不需要知道Payment的實作過程
迪米特法則就是強調類別之間互相獨立性
所以只要以參數來傳遞資訊即可
修改成:
String paymentInfo = checkout.payment.getPaymentInfo();
Receipt receipt = new Receipt(checkout.cart, total, paymentInfo);
Disclaimer
因為讀的是原文版,所以難免會有翻譯詞不達意或是專有名詞上的差異,有錯誤的話歡迎在留言區一起交流!