服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

composite模式及其在jsf组件中的应用

一 学习背景

在学习关于jsf组件时涉及到了composite模式,于是就查看一些资料,以下是自己对这种模式的理解。

二 自己整理的一些资料

1.composite模式意在组成任意复杂度的整体--部分组件层次结构,同时将单个组件或复合组件视为统一的接口。树形组织结构就是其中一种表现形式。

树形结构中有叶子结点和非叶子结点(根结点是特例),非叶子结点可以添加,删除(add(),delete())子结点,获取子结点(getchild()),叶子结点没有;此外树结构的所有节点还有共同的操作(operator()).

用户界面通常由两种基本类型的组件构造:基本组件和容器组件,容器组件可以在其内部嵌套任意数目的组件,而基本组件则不行。使用这两种组件类型,开发者可以建立更强大的组件,进而创建多姿多彩的用户界面。

但是在与复杂的组件层次结构打交道时,必须在容器组件和基本组件之间进行区分,比较麻烦,composite提供了一种解决方案。适用它的情况:

a. 要表现“部分-整体”的层次结构时

b. 希望在事件组件层次中,同等对待复合组件与单个组件。

2. 通过下面的示例来理解

示例1:

基类shape 类有两个派生类circle和square(相当于叶子结点或者是单个组件),第三个派生类compositeshape是个组合体(相当于非叶子结点或者是容器组件),它持有一个含有多个shape实例的列表,当调用compositeshape中的draw()时,它就把这个方法委托给列表中的每一个实例。

对于系统而言,一个compositeshape实例就像是一个独立的shape,可以把它传给使用shape的方法或者对象。实际上,它只是一组shape实例的proxy.

程序:

shape.java: 

public interface shape { 
    public void draw(); 
} 

compositeshape.java: 
[code]public class compositeshape implements shape { 
  private vector comshape = new vector(); 

  public void add(shape shape) { 
    comshape.add(shape); 
  } 

  public void draw() { 
    for( int i = 0; i < comshape.size(); i ++ ) { 
       shape shape = (shape) comshape.elementat(i); 
       shape.draw(); 
    } 
  } 
}

示例2:

抽象类equipment就是component定义,代表着组合体类的对象们,equipment中定义几个共同的方法。

package com.interf; 

public abstract class equipment { 
    private string name; 
    private double netprice; 
    private double discountprice; 
     
    public equipment(string name) { 
        this.name = name; 
    } 
    public abstract double netprice(); 
    public abstract double discountprice(); 
} 
disk是组合体内的一个对象,或称一个部件,这个部件是个单独元素( primitive)。
disk.java:

package implequip; 

import com.interf.equipment; 

public class disk extends equipment { 

    public disk(string name) { 
        super(name); 
        // todo auto-generated constructor stub 
    } 
     
    //定义disk实价为1 
    public double netprice() { 
        return 1.;  
    } 
    //定义了disk折扣价格是0.5 对折。 
    public double discountprice() {  
        return .5;  
    }     
} 
还有一种可能是,一个部件也是一个组合体,就是说这个部件下面还有'儿子',
这是树形结构中通常的情况,应该比较容易理解。现在我们先要定义这个组合体:
compsiteequipment.java:

package implequip; 

import java.util.arraylist; 
import java.util.iterator; 
import java.util.list; 
import java.util.nosuchelementexception; 

import com.interf.equipment; 

public class compositeequipment extends equipment { 
     
    private int i=0;  
//    定义一个vector 用来存放'儿子' 
    private list equipment = new arraylist(); 
     
    public compositeequipment(string name) { 
        super(name); 
        // todo auto-generated constructor stub 
    } 


    public boolean add(equipment equipment) {  
        this.equipment.add(equipment);  
        return true;  
    } 
    public double netprice() { 
        double netprice=0.; 
        iterator iter=equipment.iterator(); 
        while(iter.hasnext()) 
          netprice+=((equipment)iter.next()).netprice(); 
        return netprice; 
    } 

    public double discountprice() { 
        double discountprice=0.; 
        iterator iter=equipment.iterator(); 
        while(iter.hasnext()) 
          discountprice+=((equipment)iter.next()).discountprice(); 
        return discountprice; 
    } 

//    注意这里,这里就提供用于访问自己组合体内的部件方法。 
//    上面disk 之所以没有,是因为disk是个单独(primitive)的元素. 
    public iterator iter() { 
        return equipment.iterator() ; 
    } 
//    重载iterator方法 
    public boolean hasnext() { return i<equipment.size(); } 
//    重载iterator方法 
    public object next(){ 
    if(hasnext()) 
        return equipment.get(i++); 
    else  
        throw new nosuchelementexception(); 
    } 
}

上面compositeequipment继承了equipment,同时为自己里面的对象们提供了外部访问的方法,重载了iterator,iterator是java的collection的一个接口,是iterator模式的实现.

我们再看看compositeequipment的两个具体类:盘盒chassis和箱子cabinet,箱子里面可以放很多东西,如底板,电源盒,硬盘盒等;盘盒里面可以放一些小设备,如硬盘 软驱等。无疑这两个都是属于组合体性质的。

cabinet.java: 
package implequip; 

public class cabinet extends compositeequipment { 
    public cabinet(string name) { 
        super(name); 
        // todo auto-generated constructor stub 
    }     
    public double netprice() {  
        return 1.+super.netprice();  
    } 
    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.netprice();  
    } 
    public double discountprice() {  
        return .5+super.discountprice(); 
    } 
}

至此我们完成了整个composite模式的架构。我们可以看看客户端调用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="+cabinet.netprice()); 
        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(组合) 板桥里人 http://www.jdon.com 2002/04/27

网址:http://www.jdon.com/designpatterns/composite.htm

2 《mastering javaserver faces》中文版 (第一章 1.4)

3 《敏捷软件开发:原则、模式与实践》

4 《jsf实战》(t002)


扫描关注微信公众号