装饰模式2-发票系统2011-12-28 blogjava 天堂露珠[关键字]:java,design pattern,设计模式,《Java与模式》学习,decorator,装饰模式[环境]:StarUML5.0 + JDK6[作者]:Winty (wintys@gmail.com)[正文]:

package pattern.decorator.order; import java.util.*; import java.text.*; /** * 装饰模式(Decorator Pattern):发票系统 * * 发票分为三部分:发票头、发票体、发票尾。 * 其中发票头和发票尾是可能经常变化的。 * 运行结果: Bill Gates 2009-6-6 ==================== 名称 单价 数目 价格 牛奶 5.4 10 ¥54.00 面包 7.3 3 ¥21.90 沙拉 4.2 2 ¥8.40 ==================== Total Price:¥84.30 客户:Bill Gates 时间:2009-6-6 ==================== 名称 单价 数目 价格 牛奶 5.4 10 ¥54.00 面包 7.3 3 ¥21.90 ==================== Total Price:¥75.90 * @version 2009-06-06 * @author Winty(wintys@gmail.com) */ public class OrderTest{ public static void main(String[] args){ //创建商品 Item milk = new Item("牛奶",5.4,10); Item bread = new Item("面包",7.3,3); Item salad = new Item("沙拉" , 4.2 , 2); //创建发票 Order sales = new SalesOrder(); sales.setCustomerName("Bill Gates"); sales.setSalesDate(new Date()); sales.addItem(milk); sales.addItem(bread); Order order; //添加发票头尾,然后输出 order = new FooterDecorator(new HeaderDecorator(sales)); //经过装饰的order对客户端是透明的 order.addItem(salad); order.print(); System.out.println(""); //不同的包装顺序,相同顺序的输出 order = new AnotherHeaderDecorator(new FooterDecorator(sales)); //也可以安全地调用remove order.removeItem(salad); order.print(); } } /** * 商品 */ class Item{ private String name; private double price;//单价 private int amount;//购买数量 public Item(){ } public Item(String name , double price , int amount){ this.name = name; this.price = price; this.amount = amount; } public String getName(){ return this.name; } public void setName(String name){ this.name = name; } public double getPrice(){ return this.price; } public void setPrice(double price){ this.price = price; } public int getAmount(){ return this.amount; } public void setAmount(int amount){ this.amount = amount; } } /** * 抽象Component角色 */ abstract class Order{ protected List<Item> items; private String customerName; private Date salesDate; public Order(){ items = new ArrayList<Item>(); } public abstract void print(); //添加商品 public void addItem(Item item){ items.add(item); } //删除商品 public void removeItem(Item item){ items.remove(item); } public double calTotalPrice(){ double total = 0.0; Iterator<Item> list = items.iterator(); while(list.hasNext()){ Item item = list.next(); total += item.getPrice() * item.getAmount(); } return total; } public String getCustomerName(){ return customerName; } public void setCustomerName(String customerName){ this.customerName = customerName; } public Date getSalesDate(){ return salesDate; } public void setSalesDate(Date salesDate){ this.salesDate = salesDate; } public static String formatDate(Date myDate){ return DateFormat.getDateInstance().format(myDate); } public static String formatCurrency(double currency){ return NumberFormat.getCurrencyInstance().format(currency); } } /** * 具体Component角色 */ class SalesOrder extends Order{ /** * 输出商品信息 */ @Override public void print(){ printItemHeader(); Iterator<Item> list = items.iterator(); while(list.hasNext()){ print(list.next()); } } /** * 输出单个商品信息 */ private void print(Item item){ double subtotal = item.getAmount()*item.getPrice(); String str = item.getName() + ""t"; str += item.getPrice() + ""t"; str += item.getAmount() + ""t"; str += Order.formatCurrency(subtotal); System.out.println(str); } /** * 输出商品项的表头 */ private void printItemHeader(){ String header = "名称"t单价"t数目"t价格"; System.out.println(header); } } /** * 抽象装饰角色 * * 只有重新委派调用的方法(calTotalPrice()), * 或进行复制数据的方法(setCustomerName()), * 才能被多重装饰后的子类安全调用。 */ abstract class OrderDecorator extends Order{ private Order order; public OrderDecorator(Order order){ this.order = order; //未使用"委派",直接把值复制过来 this.setCustomerName(order.getCustomerName()); this.setSalesDate(order.getSalesDate()); } @Override public void print(){ order.print(); } @Override public double calTotalPrice(){ return order.calTotalPrice(); } @Override public void addItem(Item item){ order.addItem(item); } @Override public void removeItem(Item item){ order.removeItem(item); } } /** * 打印发票头的装饰 */ class HeaderDecorator extends OrderDecorator{ public HeaderDecorator(Order order){ super(order); } @Override public void print(){ printHeader(); super.print(); } private void printHeader(){ String header = getCustomerName() + ""t"; header += Order.formatDate(getSalesDate()); System.out.println(header); System.out.println("===================="); } } /** * 打印发票尾的装饰 */ class FooterDecorator extends OrderDecorator{ public FooterDecorator(Order order){ super(order); } @Override public void print(){ super.print(); printFooter(); } private void printFooter(){ String total; total = Order.formatCurrency(calTotalPrice()); System.out.println("===================="); System.out.println("Total Price:" + total); } } /** * 另一种打印发票头的装饰类 */ class AnotherHeaderDecorator extends OrderDecorator{ public AnotherHeaderDecorator(Order order){ super(order); } @Override public void print(){ printHeader(); super.print(); } private void printHeader(){ String header; header = "客户:" + getCustomerName() + ""n"; header += "时间:" + Order.formatDate(getSalesDate()); System.out.println(header); System.out.println("===================="); } }