java设计模式8:Decorator(2)

本文通过一个发票打印的例子介绍了装饰者模式的应用。该模式允许在不改变原有对象的情况下动态地增加其职责。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

又一例:

image

此例中SalesOrder为发票的主部,此处为待装饰的对象。

打印出的内容为:

FireWheel Tire    4    ¥154.23    ¥616.92
Front Fender    1    ¥300.45    ¥300.45

这对于一个发票而言,是明显不够的,需要有头部,也需要有尾部,再加上前面显示的主要部分,形成一个完整的发票。本例中考虑的是头部与尾部可能会经常更改,主体不变,因此可考虑用装饰部份,明显增强主体的功能。

本例中采用两层嵌套,来增强发票的功能,增强的代码调用如下:

order = new HeaderDecorator(new FooterDecorator(order));

产生的效果如下:

    ***    I N V O I C E    ***
XYZ Incorporated
Date of Sale: Tue Jun 21 23:33:25 CST 2011
========================================================
Item        Units    Unit Price    Subtotal
FireWheel Tire    4    ¥154.23    ¥616.92
Front Fender    1    ¥300.45    ¥300.45
========================================================
Total                ¥917.37

这样,如果以后发票头部或是尾部有所变化,可考虑修改HeaderDecorator或FooterDecorator即可。

代码如下:

package com.javapatterns.decorator.printinvoice;
 
import java.util.Date;
 
public class Client {
    /**
     * @directed 
     */
    private static Order order;
 
    public static void main(String[] args)
    {
        order = new SalesOrder();
        order.setSalesDate(new Date());
        order.setCustomerName("XYZ Repair Shop");
 
        OrderLine line1 = new OrderLine();
 
        line1.setItemName("FireWheel Tire");
        line1.setUnitPrice(154.23);
        line1.setUnits(4);
 
        order.addItem(line1);
 
        OrderLine line2 = new OrderLine();
 
        line2.setItemName("Front Fender");
        line2.setUnitPrice(300.45);
        line2.setUnits(1);
 
        order.addItem(line2);
        
        System.out.println("打印原始的发票部份");
        order.print();
 
        System.out.println("打印加上装饰后的发票");
        order = new HeaderDecorator(new FooterDecorator(order));
 
        order.print();
    }
}
 
 
package com.javapatterns.decorator.printinvoice;
 
import java.util.Date;
import java.util.Vector;
import java.text.NumberFormat;
 
abstract public class Order
{
 
    private OrderLine lnkOrderLine;
 
    protected String customerName;
 
    protected Date salesDate;
 
    protected Vector items = new Vector(10);
 
    public void print()
    {
        for (int i = 0 ; i < items.size() ; i++)
        {
            OrderLine item = (OrderLine) items.get(i);
            item.printLine();
        }
    }
 
 
    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 void addItem(OrderLine item)
    {
        items.add(item);
    }
 
    public void remoteItem(OrderLine item)
    {
        items.remove(item);
    }
 
    public double getGrandTotal()
    {
        double amnt = 0.0D;
 
        for (int i = 0 ; i < items.size() ; i++)
        {
            OrderLine item = (OrderLine) items.get(i);
            amnt += item.getSubtotal();
        }
 
        return amnt;
    }
 
    protected String formatCurrency(double amnt)
    {
        return NumberFormat.getCurrencyInstance().format(amnt);
    }
 
}
 
 
 
package com.javapatterns.decorator.printinvoice;
 
import java.text.NumberFormat;
 
public class OrderLine
{
    /**
     * @uml.property  name="itemName"
     */
    private String itemName;
    /**
     * @uml.property  name="units"
     */
    private int units;
    /**
     * @uml.property  name="unitPrice"
     */
    private double unitPrice;
 
    /**
     * @return
     * @uml.property  name="itemName"
     */
    public String getItemName()
    {
        return itemName;
    }
 
    /**
     * @param itemName
     * @uml.property  name="itemName"
     */
    public void setItemName(String itemName)
    {
        this.itemName = itemName;
    }
 
    /**
     * @return
     * @uml.property  name="units"
     */
    public int getUnits()
    {
        return units;
    }
 
    /**
     * @param units
     * @uml.property  name="units"
     */
    public void setUnits(int units)
    {
        this.units = units;
    }
 
    /**
     * @return
     * @uml.property  name="unitPrice"
     */
    public double getUnitPrice()
    {
        return unitPrice;
    }
 
    /**
     * @param unitPrice
     * @uml.property  name="unitPrice"
     */
    public void setUnitPrice(double unitPrice)
    {
        this.unitPrice = unitPrice;
    }
 
    public void printLine()
    {
        System.out.println(itemName + "/t" + units
            + "/t" + formatCurrency(unitPrice)
            + "/t" + formatCurrency(getSubtotal()));
    }
 
    public double getSubtotal()
    {
        return unitPrice * units;
    }
 
    private String formatCurrency(double amnt)
    {
        return NumberFormat.getCurrencyInstance().format(amnt);
    }
}
 
 
 
/**
 * 发票的主要部分,可以理解为原始的发票
 */
package com.javapatterns.decorator.printinvoice;
 
public class SalesOrder extends Order
{
    public SalesOrder() {
    }
 
    public void print()
    {
        super.print();
    }
}
 
 
 
/**
 * 发票主体的装饰类
 */
package com.javapatterns.decorator.printinvoice;
 
abstract public class OrderDecorator extends Order
{
    protected Order order;
 
    public OrderDecorator(Order order)
    {
        this.order = order;
        this.setSalesDate( order.getSalesDate() );
        this.setCustomerName( order.getCustomerName() );
    }
 
    public void print()
    {
        super.print();
    }
}
 
 
 
package com.javapatterns.decorator.printinvoice;
 
public class HeaderDecorator extends OrderDecorator
{
    public HeaderDecorator(Order anOrder)
    {
        super(anOrder);
    }
 
    public void print()
    {
        this.printHeader();
        super.order.print();
    }
 
    private void printHeader()
    {
        System.out.println("/t***/tI N V O I C E/t***/nXYZ Incorporated/nDate of Sale: "
            + order.getSalesDate());
        System.out.println("========================================================");
        System.out.println("Item/t/tUnits/tUnit Price/tSubtotal");
    }
}
 
 
 
package com.javapatterns.decorator.printinvoice;
 
import java.text.NumberFormat;
 
public class FooterDecorator extends OrderDecorator
{
    public FooterDecorator(Order anOrder)
    {
        super(anOrder);
    }
 
    public void print()
    {
        super.order.print();
        printFooter();
    }
 
    private void printFooter()
    {
 
        System.out.println("========================================================");
        System.out.println("Total/t/t/t/t" +
            formatCurrency(super.order.getGrandTotal()));
    }
 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

永远的麦田

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值