浏览 1295 次
锁定老帖子 主题:Composite模式及其在JSF中的应用
该帖已经被评为隐藏帖
|
|
---|---|
作者 | 正文 |
发表时间:2008-04-14
在学习关于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: 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用来收集用户输入的数据,并在需要时重新封闭到页面中 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |