随笔 - 117  文章 - 72  trackbacks - 0

声明:原创作品(标有[原]字样)转载时请注明出处,谢谢。

常用链接

常用设置
常用软件
常用命令
 

订阅

订阅

留言簿(7)

随笔分类(130)

随笔档案(123)

搜索

  •  

积分与排名

  • 积分 - 154450
  • 排名 - 389

最新评论

[关键字]: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("====================");
    }
}

posted on 2009-06-07 22:37 天堂露珠 阅读(1624) 评论(1)  编辑  收藏 所属分类: Pattern

FeedBack:
# re: [原]装饰模式2-发票系统 2013-08-10 11:31 dohkoos
为了模式而模式,很无聊!

public class Invoice {
public void print() {
printHeader();
printBody();
printFooter();
}
}
  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
博客园   IT新闻   Chat2DB   C++博客   博问