隨筆 - 117  文章 - 72  trackbacks - 0

          聲明:原創作品(標有[原]字樣)轉載時請注明出處,謝謝。

          常用鏈接

          常用設置
          常用軟件
          常用命令
           

          訂閱

          訂閱

          留言簿(7)

          隨筆分類(130)

          隨筆檔案(123)

          搜索

          •  

          積分與排名

          • 積分 - 155796
          • 排名 - 390

          最新評論

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

          FeedBack:
          # re: [原]裝飾模式2-發票系統 2013-08-10 11:31 dohkoos
          為了模式而模式,很無聊!

          public class Invoice {
          public void print() {
          printHeader();
          printBody();
          printFooter();
          }
          }
            回復  更多評論
            
          主站蜘蛛池模板: 洛宁县| 德钦县| 星座| 遵化市| 林周县| 杭锦旗| 团风县| 会理县| 攀枝花市| 巩留县| 元阳县| 西华县| 运城市| 上思县| 井陉县| 崇阳县| 新源县| 五莲县| 伊宁市| 漠河县| 仁怀市| 内丘县| 开化县| 正安县| 高雄市| 凌海市| 合山市| 宣化县| 永清县| 收藏| 黑山县| 乌兰浩特市| 连山| 萨迦县| 民勤县| 水富县| 团风县| 响水县| 平顺县| 岚皋县| 中牟县|