熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java高級技術 >> 正文

Composite模式及其在JSF中的應用

2013-11-23 19:50:39  來源: Java高級技術 
一 學習背景

   在學習關於JSF組件時涉及到了composite模式於是就查看一些資料以下是自己對這種模式的理解

二  自己整理的一些資料(見參考資料)

posite模式意在組成任意復雜度的整體部分組件層次結構同時將單個組件或復合組件視為統一的接口樹形組織結構就是其中一種表現形式

樹形結構中有葉子結點和非葉子結點(根結點是特例)非葉子結點可以添加刪除(add()delete())子結點獲取子結點(getChild())葉子結點沒有此外樹結構的所有節點還有共同的操作(operator())
用戶界面通常由兩種基本類型的組件構造基本組件和容器組件容器組件可以在其內部嵌套任意數目的組件而基本組件則不行使用這兩種組件類型開發者可以建立更強大的組件進而創建多姿多彩的用戶界面
但是在與復雜的組件層次結構打交道時必須在容器組件和基本組件之間進行區分比較麻煩composite提供了一種解決方案適用它的情況
a 要表現部分整體的層次結構時
b 希望在事件組件層次中同等對待復合組件與單個組件

 通過下面的示例來理解
示例 
基類shape 類有兩個派生類Circle和Square(相當於葉子結點或者是單個組件)第三個派生類CompositeShape是個組合體(相當於非葉子結點或者是容器組件)它持有一個含有多個shape實例的列表當調用CompositeShape中的draw()時它就把這個方法委托給列表中的每一個實例
 
對於系統而言一個CompositeShape實例就像是一個獨立的shape可以把它傳給使用shape的方法或者對象實際上它只是一組shape實例的proxy
程序


    Shapejava:

    Public interface Shape {
        Public void draw();
    }

    CompositeShapejava:
    [code]Public class CompositeShape implements Shape {
      private Vector Comshape = new Vector();

      public void add(Shape shape) {
        Comshapeadd(shape);
      }

      Public void draw() {
        forint i = ; i < comshapesize(); i ++ ) {
           Shape shape = (Shape) comshapeelementAt(i);
           Shapedraw();
        }
      }
    }

示例 
抽象類Equipment就是Component定義代表著組合體類的對象們Equipment中定義幾個共同的方法


    package cominterf;

    public abstract class Equipment {
        private String name;
        private double netPrice;
        private double discountPrice;
        
        public Equipment(String name) {
            thisname = name;
        }
        public abstract double netPrice();
        public abstract double discountPrice();
    }
Disk是組合體內的一個對象或稱一個部件這個部件是個單獨元素( Primitive)
Diskjava:


    package implEquip;

    import cominterfEquipment;

    public class Disk extends Equipment {

        public Disk(String name) {
            super(name);
            // TODO Autogenerated constructor stub
        }
        
        //定義Disk實價為
        public double netPrice() {
            return 
        }
        //定義了disk折扣價格是 對折
        public double discountPrice() { 
            return 
        }    
    }
還有一種可能是一個部件也是一個組合體就是說這個部件下面還有兒子這是樹形結構中通常的情況應該比較容易理解現在我們先要定義這個組合體
CompsiteEquipmentjava:


    package implEquip;

    import javautilArrayList;
    import javautilIterator;
    import javautilList;
    import javautilNoSuchElementException;

    import cominterfEquipment;

    public class CompositeEquipment extends Equipment {
        
        private int i=
    //    定義一個Vector 用來存放兒子
        private List equipment = new ArrayList();
        
        public CompositeEquipment(String name) {
            super(name);
            // TODO Autogenerated constructor stub
        }


        public boolean add(Equipment equipment) { 
            thisequipmentadd(equipment); 
            return true
        }
        public double netPrice() {
            double netPrice=;
            Iterator iter=erator();
            while(iterhasNext())
              netPrice+=((Equipment)iternext()Price();
            return netPrice;
        }

        public double discountPrice() {
            double discountPrice=;
            Iterator iter=erator();
            while(iterhasNext())
              discountPrice+=((Equipment)iternext())discountPrice();
            return discountPrice;
        }

    //    注意這裡這裡就提供用於訪問自己組合體內的部件方法
    //    上面dIsk 之所以沒有是因為Disk是個單獨(Primitive)的元素
        public Iterator iter() {
            return erator() ;
        }
    //    重載Iterator方法
        public boolean hasNext() { return i<equipmentsize(); }
    //    重載Iterator方法
        public Object next(){
        if(hasNext())
            return equipmentget(i++);
        else 
            throw new NoSuchElementException();
        }
    }

  上面CompositeEquipment繼承了Equipment同時為自己裡面的對象們提供了外部訪問的方法重載了IteratorIterator是Java的Collection的一個接口是Iterator模式的實現
我們再看看CompositeEquipment的兩個具體類:盤盒Chassis和箱子Cabinet箱子裡面可以放很多東西如底板電源盒硬盤盒等盤盒裡面可以放一些小設備如硬盤 軟驅等無疑這兩個都是屬於組合體性質的



    Cabinetjava:
    package implEquip;

    public class Cabinet extends CompositeEquipment {
        public Cabinet(String name) {
            super(name);
            // TODO Autogenerated constructor stub
        }    
        public double netPrice() { 
            return +super    }
        public double discountPrice() { 
            return .5+super.discountPrice();
        }
    }



Chassi.java:


    package implEquip;

    public class Chassis extends CompositeEquipment {

        public Chassis(String name) {
            super(name);
            // TODO Auto-generated constructor stub
        }
        public double netPrice() { 
            return 1.+super    }
        public double discountPrice() { 
            return .5+super.discountPrice();
        }
    }

至此我們完成了整個Composite模式的架構。Tw.WiNGWIt.com我們可以看看客戶端調用Composote代碼:

CompositeTest.java:


    package test;

    import implEquip.Cabinet;
    import implEquip.Chassis;
    import implEquip.Disk;

    public class CompositeTest {

        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Cabinet cabinet=new Cabinet("Tower");
            Chassis chassis=new Chassis("PC Chassis");
    //        將PC Chassis裝到Tower中 (將盤盒裝到箱子裡)
            cabinet.add(chassis);
    //        將一個10GB的硬盤裝到 PC Chassis (將硬盤裝到盤盒裡)
            chassis.add(new Disk("10 GB"));

    //        調用 netPrice()方法;
            System.out.println("netPrice="+Price());
            System.out.println("discountPrice="+cabinet.discountPrice());

        }

    }

上面調用的方法netPrice()或discountPrice(),實際上Composite使用Iterator遍歷了整個樹形結構,尋找同樣包含這個方法的對象並實現調用執行.
控制台輸出:
netPrice=3.0
discountPrice=1.5

三.JSF組件提供的實現非常接近Composite模式給出的一般性解決方案,不過(和Swing不同)這裡的頂層和一般組件之間沒有明顯差異。
JSF提供了一個所有組件都要實現的UIComponent接口,UIComponentBase類為了方便組件開發者,定義了默認的行為。JSF有許多基本組件如UIForm和UIInput。另外可以創建自己的自定義組件。創建自定義組件時,必須要實現UIComponent接口或者繼承UIComponentBase類
JSF為使用默認組件提供了方便的標記庫。當頁面被應用的用戶提交時,FacesServlet 將根據這些標記所提供和搜集的信息實際建立一個組件樹(本人想法:具體建樹過程以及管理被封裝起來了,在管理和使用UI組件的原理應該同composite模式一致;實際是什麼???能找到實現的代碼最好了)
 
第一層:form
第二層:label,outputtext,panel
第三層:command1 command2

UI組件是在服務器的視圖或者組件樹中進行管理,組件可以直接關系到JavaBean屬性的值(任何遵循了JavaBean命名約定的Java對象都可以為JSF組件命使用),在客戶端表現為HTML語言(或者其他顯示語言)。JavaBean用來收集用戶輸入的數據,並在需要時重新封閉到頁面中。

四.參考資料:
 1 設計模式之Composite(組合)  板橋裡人 ;2002/04/27 
   網址:
 2 《Mastering JavaServer Faces》中文版 (第一章 1.4) 
 3 《敏捷軟件開發:原則、模式與實踐》
 4.《JSF實戰》


From:http://tw.wingwit.com/Article/program/Java/gj/201311/27549.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.