一 学习背景
在学习关于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用来收集用户输入的数据,并在需要时重新封闭到页面中。
四.参考资料:
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实战》
分享到:
相关推荐
在JSF框架中,此模式用于动态创建对象,比如在生命周期管理中,LifeCycle接口的实现可能会根据配置使用不同的工厂方法来创建PhaseListener对象,这提供了更大的灵活性和可扩展性。 4. **State模式**: State模式...
《JSF中文教程》可能是这方面的资源,它可能涵盖了JSF的基础知识、进阶主题和实际案例,旨在帮助开发者快速上手并熟练运用JSF开发Web应用。 通过深入学习JSF,开发者不仅可以提高Web应用的开发效率,还能利用Java ...
EL是一种简洁的脚本语言,用于在JSF中获取和设置Managed Beans的属性值。它允许在JSF视图中直接引用后台Bean的属性,简化了数据绑定的过程。 **6. 视图和导航** JSF的视图通常由Facelets文件(.xhtml)组成,它们...
1. **JSF生命周期**:JSF应用的每个请求都会经历一系列的阶段,包括恢复视图、应用请求值、处理验证、更新模型值、调用应用逻辑和渲染响应。理解这些阶段对于调试和优化JSF应用至关重要。 2. **组件模型**:JSF的...
这个压缩包文件"myfaces-example-simple-1.1.7-SNAPSHOT"包含了一个JSF的实际应用示例,适合初学者和开发者了解JSF标签的使用方法和JSF应用的部署流程。 首先,我们要理解JSF的核心概念:组件、事件和渲染。JSF中的...
每个阶段都有特定的任务,理解这个生命周期对于调试和优化JSF应用至关重要。 7. **转换和验证**:JSF允许在接收和显示数据时进行转换和验证。转换用于将用户输入的数据转化为应用程序所需的格式,验证则确保数据...
5. **国际化支持**:JSF支持多语言,这在“JSF中文使用教程”中可能包含如何设置和使用中文资源的内容。 **学习JSF的关键概念**: 1. **Facelet**:Facelets是JSF的默认视图技术,用于创建和组织用户界面组件。 2. ...
本教程将深入探讨JSF的核心概念以及如何在JSF应用中传递参数,帮助开发者更好地理解和掌握这一技术。 首先,让我们理解**JSF的基本架构**。JSF的核心组件包括视图、控制器和模型,它们共同构成了MVC(Model-View-...
在本项目中,我们将利用JSF来创建一个功能完善的购物车应用。 首先,我们需要了解**NetBeans IDE**。这是一个强大的集成开发环境,特别适合Java开发者,提供了对JSF的全面支持,包括代码提示、模板和调试工具,使得...
在JSF中,导航是控制应用程序流程的重要部分。开发者可以定义导航规则来指定用户操作后的页面跳转,这些规则通常在faces-config.xml配置文件中定义。导航规则使得开发者能更好地控制用户在应用程序中的路径。 JSF的...
在本文中,我们将深入探讨如何在NetBeans IDE中开发基于JavaServer Faces (JSF)的应用。JSF是一种Java EE框架,专门设计用于构建Web应用...通过实践上述步骤,开发者可以迅速掌握在NetBeans中开发JSF应用的基本流程。
通过API,你可以了解如`UIComponent`、`ManagedBean`、`PhaseListener`等关键概念,这些都是构建JSF应用程序的基础。 **Java** 是JSF的底层语言,JSF的组件和事件处理都是基于Java的。了解Java语言的基本语法和面向...
但是,根据上下文,我们可以推断文档可能包含有关JSF的详细教程或参考资料,比如如何配置JSF环境、创建JSF组件、处理用户事件以及调试JSF应用程序等内容。 总的来说,JSF是一个强大的工具,它为Java开发者提供了...
在IT行业中,JavaScript框架(JSF,JavaServer Faces)是一种广泛应用的用于构建Web应用程序的UI层技术。...在实际工作中,理解和掌握这些知识点对于优化JSF应用的用户体验,尤其是对于中文用户来说,是非常重要的。
最后,JSF与其他Java EE技术如EJB、JPA、CDI等有良好的集成,这使得在大型企业级应用中使用JSF成为可能。通过这些集成,开发者可以方便地利用现有的服务和数据存储技术,构建出复杂且健壮的应用系统。 总的来说,...
通过研究这个例子,可以更好地理解JSF的工作原理以及如何在实际项目中应用DataGrid。 总的来说,JSF提供了一套完整的Web应用开发框架,DataGrid是其展示数据的强大工具。通过熟练掌握JSF和DataGrid的使用,开发者...
JSF是一种用于构建Java ... 包含JSP页面的JSF应用程序也使用由为了表现UI组件和在页面上的其他对象的JSF技术而定义的标准的tag库。 Java Server Faces技术的重要开发框架 sun-ri、myfaces、icefaces、richfaces、seam
为了配置JSF应用程序,开发者需要创建`faces-config.xml`配置文件,其中包含: - **管理Bean配置**:定义Bean的名称、类以及作用域(例如,请求、会话、应用范围)。 - **导航规则**:定义用户操作与页面跳转之间的...