又一例:
此例中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()));
}
}