[關鍵字]: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
天堂露珠 閱讀(1637)
評論(1) 編輯 收藏 所屬分類:
Pattern