Welcome

首页 / 软件开发 / 数据结构与算法 / 装饰模式2-发票系统

装饰模式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("====================");    }  }