首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

用 JavaServer Faces 2 实现可扩展 UI (3)

用 JavaServer Faces 2 实现可扩展 UI (3)

技巧 2:使用组合的方式在我的 CAD/CAM GUI 发布后不久,我花了几个月的时间与另一位开发人员 Bob 致力于一个新的项目。我们以 Bob 的代码为基础,而且不可思议地是,我们还能轻松进行更改并修复 bug。
我很快意识到 Bob 的代码和我的代码之间的最大区别是他编写了 方法 — 通常是在代码的 5 至 15 行之间 — 并且他的整个系统都是由这些小方法拼接而成的。在我还在忙着修改我之前项目中具有很多关注点的长方法时,Bob 已经开始机敏地组合小方法和原子功能性了。Bob 的代码和我的代码在维护性和可扩展性方面自然也有着天壤之别,从那以后,我开始信服小方法。
虽然 Bob 和我那时都没有意识到,但是我们过去一直在使用 Smalltalk 的一种设计模式,称为 Composed Method(参见 ):
在一个抽象级别,将软件分成能执行单个任务的多个方法。
使用 Composed Method 模式的好处已经有大量书面记载(详细说明,请参见 Neal Ford 的 “” )。在这里,我将侧重于介绍如何在 JSF 视图中使用 Composed Method 模式。
JSF 2 鼓励使用较小的视图段组装视图。模板封装了常见功能,进而将视图分成了更小的块。JSF 2 还提供了一个 <ui:include> 标记,正如我在先前的代码清单中所展示的,这个标记可以让您将视图进一步分成更小的功能块。比如,图 2 展示了 places 应用程序的 login 页面的左菜单:
图 2. login 页面的左菜单清单 5 显示了定义该菜单内容的文件:
清单 5. login 视图左菜单的实现
1
2
3
4
5
6
7
8
9
10
11
12
13
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:ui="http://java.sun.com/jsf/facelets">

  <div class="menuLeftText">
    #{msgs.welcomeGreeting}

    <div class="welcomeImage">
      <h:graphicImage library="images" name="cloudy.gif"/>
    </div>
  </div>
     
</html>




内的标记很简单,这就使文件更易于阅读、理解、维护和扩展。如果相同的代码埋藏在一个很长的、包含实现 login 视图所需的全部内容的 XHTML 页面内,那么它更改起来将会很繁琐。
图 3 显示了 places 视图的左菜单:
图 3. places 视图的左菜单places 视图的左菜单的实现如清单 6 所示:
清单 6. places 视图的左菜单的实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:util="http://java.sun.com/jsf/composite/components/util">

  <div class="placesSearchForm">
    <div class="placesSearchFormHeading">
      #{msgs.findAPlace}
    </div>   
     
    <h:form prependId="false">
      <h:panelGrid columns="2">
        
        #{msgs.streetAddress}
        <h:inputText value="#{place.streetAddress}" size="15"/>
         
        #{msgs.city}  <h:inputText value="#{place.city}"  size="10"/>
        #{msgs.state} <h:inputText value="#{place.state}" size="3"/>
        #{msgs.zip}   <h:inputText value="#{place.zip}"   size="5"/>
         
        <h:commandButton value="#{msgs.goButtonText}"
          style="font-familyalatino;font-style:italic"
          action="#{place.fetch}"/>
                        
      </h:panelGrid>         
    </h:form>
  </div>
     
  <util:icon image="#{resource['images:back.jpg']}"
    actionMethod="#{places.logout}"
    style="border: thin solid lightBlue"/>

</ui:composition>

返回列表