建立一個超市收銀程式,支援商品輸入、價格計算、折扣處理、格式化輸出小票。
// 商品實體
class Product {
String id, name;
double price;
int stock;
}
// 購物車項目
class CartItem {
Product product;
int quantity;
double subtotal() { return product.price * quantity; }
}
// 收銀主邏輯
class Cashier {
List<CartItem> cart = new ArrayList<>();
Map<String, Product> products = new HashMap<>();
void addProduct(Product p) { products.put(p.id, p); }
boolean scan(String productId, int qty) {
Product p = products.get(productId);
if (p == null || p.stock < qty) return false;
cart.add(new CartItem(p, qty));
p.stock -= qty;
return true;
}
double calculateTotal() {
return cart.stream().mapToDouble(CartItem::subtotal).sum();
}
String printReceipt() {
StringBuilder sb = new StringBuilder();
sb.append("=== 超市小票 ===\n");
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
sb.append("時間: ").append(LocalDateTime.now().format(fmt)).append("\n");
sb.append(String.format("%-15s %5s %8s %8s\n", "商品", "單價", "數量", "小計"));
sb.append("--------------------------------\n");
for (CartItem item : cart) {
sb.append(String.format("%-15s %5.2f %5d %8.2f\n",
item.product.name, item.product.price, item.quantity, item.subtotal()));
}
sb.append("--------------------------------\n");
sb.append(String.format("%28s %8.2f\n", "總計:", calculateTotal()));
sb.append("================================");
return sb.toString();
}
}
public static void main(String[] args) {
Cashier cashier = new Cashier();
// 初始化商品
cashier.addProduct(new Product("001", "蘋果", 5.0, 100));
cashier.addProduct(new Product("002", "香蕉", 3.5, 50));
cashier.addProduct(new Product("003", "牛奶", 12.0, 30));
Scanner sc = new Scanner(System.in);
while (true) {
System.out.print("掃碼/輸入商品ID (q結帳, x退出): ");
String input = sc.nextLine().trim();
if ("x".equalsIgnoreCase(input)) break;
if ("q".equalsIgnoreCase(input)) {
System.out.println(cashier.printReceipt());
cashier = new Cashier(); // 重置
continue;
}
System.out.print("數量: ");
int qty = sc.nextInt(); sc.nextLine();
if (!cashier.scan(input, qty)) {
System.out.println("商品不存在或庫存不足");
}
}
}
| 功能 | 實作要點 |
|---|---|
| 會員折扣 | Strategy 模式:DiscountStrategy 介面,VipDiscount/NormalDiscount 實作 |
| 促銷活動 | 買二送一、滿減:PromotionEngine 處理規則 |
| 多種支付 | Command 模式:PaymentCommand,支援現金/刷卡/掃碼 |
| 小票列印 | ESC/POS 指令或 Java Print Service API |
| 資料持久化 | SQLite / H2 嵌入式資料庫 |
// String.format 格式化
String.format("%-20s %8.2f", "商品名", 12.5); // 左對齊20寬,右對齊8寬2位小數
// DecimalFormat 貨幣格式
DecimalFormat money = new DecimalFormat("¥#,##0.00");
money.format(1234.5); // "¥1,234.50"
// 對齊小票 (等寬字體環境)
System.out.printf("%-16s %6s %4s %8s%n", "商品", "單價", "量", "小計");
