[关键字]: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
天堂露珠 阅读(1622)
评论(1) 编辑 收藏 所属分类:
Pattern