??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲免费视频播放,亚洲AV综合色区无码另类小说,亚洲邪恶天堂影院在线观看http://m.tkk7.com/canonical/archive/2010/01/17/309866.htmlcanonicalcanonicalSun, 17 Jan 2010 09:51:00 GMThttp://m.tkk7.com/canonical/archive/2010/01/17/309866.htmlhttp://m.tkk7.com/canonical/comments/309866.htmlhttp://m.tkk7.com/canonical/archive/2010/01/17/309866.html#Feedback0http://m.tkk7.com/canonical/comments/commentRss/309866.htmlhttp://m.tkk7.com/canonical/services/trackbacks/309866.html
1. 识别contextPath
   tpl模板中的所有资源相x{N?x)自动拼接Web应用的contextPath, 例如当contextPath=myApp?br />    <script src="/a.js"></script> 最l输?<script src="/myApp/a.js" ...>

2. 识别重复装蝲
   <script src="a.js" tpl:once="true"></script>
   tpl:once属性将保证在页面中script标签实际只会(x)出现一?

3. 识别lg内相对\?br />   开发Weblg?我们希望所有资源文仉应该相对lg目录q行定位,但是直接输出?lt;script>{标{N是相对于最l的调用链接q行相对路径定位? 例如在page1.jsp中调用了lgA, 在组件A的实C, 输出?lt;script src="my_control.js"></script>
 我们的意图一般是相对于组件A的实现文件进行定? 而不是相对于page1.jspq行定位. tpl模板引擎的相对\径解析规则ؓ(f)永远相对于当前文件进行定? 例如
  <c:include src="sub.tpl" />
在sub.tpl中的所有相对\径都相对于sub.tpl文gq行定位.

4. ~译期文件有效性检?br />    在编译期, tpl引擎?x)检查所有引入的资源文g的有效? 如果发现资源文g丢失, 直接抛出异? q样׃用等CU后才发现文件命名已修改{问?

5. ~存控制
  览器缺省会(x)~存css, js{文? 因此pȝ上线后如果修改资源文件可能会(x)造成与客L(fng)~存不一致的情况. 一个简单的处理方式是每ơ生成资源链接的时候都拼接文g的修Ҏ(gu)期或者版本号, q样既可利用客户端缓? 又可以保证L使用最新版? 例如
  <script src="a.js"></script>会(x)输出 <script src="/myApp/myModule/a.js?344566" ...>

6. 字符集选择
  Z化国际化处理, 一般提倡的最?jng)_跉|式是坚持使用UTF-8~码. 但是很多情况下可能用系l内|的GBK~码?x)更加方便一? 另外集成一些既有代码时也存在着不同字符集的问题. 在Witrixq_? 所有输出的资源标签都会(x)标明对应的字W集, 如果没有明确讄取pȝ参数中的~省字符?
 例如 <script src="a.js"></script> 会(x)输出 <script ... charset="GBK"></script>

7. ~省theme支持
  Z支持多种面风格, 往往不是单的替换css文g卛_实现? 它可能意味着整个lg的实C码的更换. Witrixq_中通过一pd~省判断来简化这一q程. 例如如下代码表明如果讄了ui_themepȝ参数, q且对应的特D实现存? 则用特D实? 否则pȝ~省实现.
  <c:include src="${cp:ui_theme()}/ctl_my_ctl.tpl" >
    <c:include src="default/ctl_my_ctl.tpl" />
  </c:include>


canonical 2010-01-17 17:51 发表评论
]]>
AOP的应?/title><link>http://m.tkk7.com/canonical/archive/2009/12/13/305770.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Sun, 13 Dec 2009 03:34:00 GMT</pubDate><guid>http://m.tkk7.com/canonical/archive/2009/12/13/305770.html</guid><wfw:comment>http://m.tkk7.com/canonical/comments/305770.html</wfw:comment><comments>http://m.tkk7.com/canonical/archive/2009/12/13/305770.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/canonical/comments/commentRss/305770.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/canonical/services/trackbacks/305770.html</trackback:ping><description><![CDATA[<p>     AOP(Aspect Oriented Programming)早已不是什么新鲜的概念Q但有趣的是Q除了事?transaction), 日志(Log){寥寥几个样板应用之外,我们g找不到它的用武之地?a mce_href="/blog/34941">http://canonical.javaeye.com/blog/34941</a> 很多人的疑惑是我直接改代码就行了Q干吗要用AOP呢?AOP的定义和实现那么复杂Q能够提供什么特异的价值呢Q?br />     Witrixq_依赖于AOP概念来完成领域模型抽象与模型变换Q但是在具体的实现方式上Q却与常见的AOP软g包有着很大差异?a mce_href="/blog/542622">http://canonical.javaeye.com/blog/542622</a> AOP的具体技术内容包括定位和l装两个部分。简化切点定位方式和重新规划l装I间Q是Witrix中有效用AOP技术的前提?br />     在Witrixq_中,对于AOP技术的一U具体应用是支持产品的二ơ开发。在产品的实施过E中Q经帔R要根据客L(fng)特定需求,修改某些函数的实现。我? 可以选择在主版本代码中不断追加相互纠~的if-else语句Q试囑֎包容所有已知和未知的应用场景。我们也可以选择ȝ本代码和定制代码独立开发的? 式,ȝ本代码实现逻辑框架Q定制代码通过AOP机制与主版本代码融合Q根据具体场景要求对ȝ本功能进行修正。AOP的这U应用与所谓的横切概念是有所 区别的。典型的Q一个横切的切点?x)涉及(qing)到很多cȝ很多Ҏ(gu)Q而函数定制则往往要求准确定位到某个业务对象的某个特定的业务方法上。传lAOP技术的切点? 义方式ƈ不适合q种_的单点定位。在Witrixq_中,我们通过直接的名U映来定义切点。例如,修正spring中注册的MyObject对象? myFuncҎ(gu)Q可以在app.aop.xml文g中增加如下标{?br /> </p> <div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000ff;"><</span><span style="color: #800000;">myObject</span><span style="color: #ff0000;">.myFunc</span><span style="color: #0000ff;">></span><span style="color: #000000;"><br />       在原函数执行之前执行<br />       </span><span style="color: #0000ff;"><</span><span style="color: #800000;">aop:Proceed</span><span style="color: #0000ff;">/></span><span style="color: #000000;"> </span><span style="color: #008000;"><!--</span><span style="color: #008000;"> 执行原函数内?nbsp;</span><span style="color: #008000;">--></span><span style="color: #000000;"><br />       在原函数执行之后执行<br /> </span><span style="color: #0000ff;"></</span><span style="color: #800000;">myObject.myFunc</span><span style="color: #0000ff;">></span><span style="color: #000000;"><br /> <br /> </span></div> <br /> <p> [spring对象?Ҏ(gu)名]q种映射Ҏ(gu)比基于正则字W串匚w的方式要单明的多。spring容器本n已经实现了对象的全局理功能Qspring对象名称必然是唯一的,公开发布的,怺之间不冲H的Q没有必要再通过匚wq算重新发现出它的唯一性?br />    对于一些确实存在的横切需求,我们可以通过Annotation机制来实现切点坐标标定,复杂的切点匚w问题重新划归为[对象?Ҏ(gu)名]?br /> </p> <div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #000000;">@AopClass({"myObject","otherObject"})<br />   class SomeClass{<br />      @AopMethod({"myFunc","otherFunc"})<br />      void someFunc(){}<br />   }<br /> <br /> </span></div>   <p>针对以上对象Q在app.aop.xml文g中可以定?/p> <div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000ff;"><</span><span style="color: #800000;">I-myObject</span><span style="color: #ff0000;">.I-myFunc</span><span style="color: #0000ff;">></span><span style="color: #000000;"><br />    <img src="http://m.tkk7.com/Images/dot.gif" alt="" />.<br /> </span><span style="color: #0000ff;"></</span><span style="color: #800000;">I-myObject.I-myFunc</span><span style="color: #0000ff;">></span><span style="color: #000000;"><br /> <br /> </span></div> <img src ="http://m.tkk7.com/canonical/aggbug/305770.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/canonical/" target="_blank">canonical</a> 2009-12-13 11:34 <a href="http://m.tkk7.com/canonical/archive/2009/12/13/305770.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>HTML模型增强http://m.tkk7.com/canonical/archive/2009/05/30/278973.htmlcanonicalcanonicalFri, 29 May 2009 16:44:00 GMThttp://m.tkk7.com/canonical/archive/2009/05/30/278973.htmlhttp://m.tkk7.com/canonical/comments/278973.htmlhttp://m.tkk7.com/canonical/archive/2009/05/30/278973.html#Feedback2http://m.tkk7.com/canonical/comments/commentRss/278973.htmlhttp://m.tkk7.com/canonical/services/trackbacks/278973.html  
   Witrixq_中对于前台html模型也作了一定的增强Q但基本的设计思想是尽量利用原生控Ӟq尽量保持原生控件内在的数据关系Q而不是重新构Z个完整的底层支撑环境。采用这U设计的原因大致有如下几点:(x)
1. 前台技术目前竞争非常激烈,我们优先选择的方式是集成W三方组Ӟ量保持原生环境有利于降低集成成本?br /> 2. 通过javascript构造的控g可能存在性能瓉和其他浏览器内在的限制。例如一般Ajax框架提供的Grid控g都无法支撑大量单元格的显C?br /> 3. Witrixq_的tpl模板技术可以非常方便的生成html文本Qƈ提供强大的控件抽象能力,因此在前台动态创建ƈl织界面元素在Witrixq_中是一U不l济的做法?br /> 4. Witrixq_提供的分解机刉常细_(d)存储于不同地方的不同来源的代码会(x)在不同的时刻l入到最l的面中,Z原生环境有利于降低^台快速演q过E中的设计风险?br />
   Witrixq_中对于html模型的增Z要关注于以最的代码实现界面控g与业务逻辑的自然结合。基本结构包括:(x)
1. 通过ControlManager对象在前台徏立一Ucontainerl构Q统一理控g的注册和获取。js.makeControl(elmOrId)q回Ҏ(gu)注册的控件对象或者根据原生html元素生成一个包装对象?br /> 2. 通过js.getWxValue(elm)和js.setWxValue(elm,value)q两个函数统一Ҏ(gu)件的值的存取q程?br /> 3. 通过js.regListener(elm,listenerFunc)l一理控g之间的相兌发,实现控g之间的相互监听。当js.setWxValue(elm,value)被调用时Q注册在ControlManager中的listenerFunc被调用?br /> 4. stdPage.setFieldValue(fieldName,value)和stdPage.getFieldValue(fieldName,value)l一针对业务字段的值的存取q程Q这里fieldName对应于实体上的业务字D名?br /> 5. 通过ajax.addForm(frmId){函数统一前台提交参数的提取过E,通过stdPage.buildAjax(){函数统一后台服务的调用方式?br /> 6. 通过stdPage对象l一装业务场景中的"常识"?br /> Z以上一些基机制QW(xu)itrixq_卛_提供一些复杂的业务lg装。例?lt;input name="productCode" onkeypress="stdPage.keyPressToLoadRefByCode({objectName:'SomeProduct',queryField:'productCode'})" .../>通过单的调用一个js函数卛_实现如下功能Q?br /> a. 在文本框中输入回车的时候自动提交到后台查找对应产品代码的品,q更新前台多个相兛_D늚?br /> b. 如果没有查找到相应品,则弹出对话框Ҏ(gu)界面上已有的部分字段信息提示客户d新的产品信息?br /> c. 如果扑ֈ多个对应产品Q则弹出列表允许客户选择其一?br /> d. 具体的处理过E可以通过函数参数q行_的控制?br /> 在meta文g中,l合上下文环境中的元数据信息Q我们在~省情况下可以直接?<ds:LoadRefByCodeInputor objectName="SomeProduct" />标签Q不需要Q何其他附加参数?br />
   Witrixq_中一般利用原生控件来保存数据|而不是将数据保存在分ȝjs对象中。例如对于一个选择控gQ经常要求选择得到的是实体的id,而显C在界面上的是某个其他字D늚倹{Witrixq_中一般的实现l构?br />    <input type="hidden" name="${fieldName}" value="${entity[dsMeta.idField]}" id="${id}" textId="text_${id}" />
   <input type="text" value="${entity[dsMeta.nameField]}" id="text_${id}" />
通过textId{扩展属性即可明定义控件多个部分之间的兌关系Q同时保证控件的实现完全与html规范相兼宏V?br />    Witrixq_中目前用的"标准?的扩展属性有textId(对应文本昄控g的id), showName(某些无文字显C的选择控g需要保留显C字D?, op(字段作ؓ(f)查询条g提交时的比较符)Qvalidator(字段值对应的验函?QsetWxValue/getWxValue(重定义控件值的存取行ؓ(f))Qserializer(Ҏ(gu)处理前台控g的提交参?{。扩展属性不仅可以引入说明信息,q可以引入丰富的控g行ؓ(f)?br />   




canonical 2009-05-30 00:44 发表评论
]]>
报表引擎Q结构生成与l构转换http://m.tkk7.com/canonical/archive/2007/09/02/142036.htmlcanonicalcanonicalSun, 02 Sep 2007 01:45:00 GMThttp://m.tkk7.com/canonical/archive/2007/09/02/142036.htmlhttp://m.tkk7.com/canonical/comments/142036.htmlhttp://m.tkk7.com/canonical/archive/2007/09/02/142036.html#Feedback1http://m.tkk7.com/canonical/comments/commentRss/142036.htmlhttp://m.tkk7.com/canonical/services/trackbacks/142036.html    Witrixq_的报表引擎是对程序友好的Q它引入了编译期l构q算Q在报表~译时可以通过E序吸收大部分结构差异性。在Witrixq_中,报表制作分ؓ(f)三个阶段Q设计期 -> ~译?-> q行期。报表引擎负责完成三U工作:(x)l构描述Q结构生成和l构转换。具体实现动态结构生成的q程其实非常单。目前所有的Witrix配置文g都通过基础配置引擎q行解析Q它定义了统一的dynamic和extends元机制?br />    <report dynamic="true">
定义了dynamic="true"的报表定义文仉先作为tpl模板文g来运行,其运行结果再作ؓ(f)报表格式解析。在q种模型下,报表引擎q没有内|如何把动态结构拼接出来的知识Q这些知识存在于~译期,而tpl标签的抽象能力得我们可以把复杂的报表结构生成过E抽象成单的标签调用形式?br />    <report dynamic="true">
      <body>
        <table>
         <thead>
            <c:forEach var="_h" items="${cols}">
             ....
        </table>
      </body>
   </report>

==>
   <report dynamic="true">
      <body>
         <rpt:GenCrossTable tableMeta="${tableMeta}" loopVar="tableData" />
      </body>
   </report>

   在编译期通过tpl装可以解决大部分结构生成问题,在运行期报表引擎主要负责的结构问题就化ؓ(f)数据行展开和单元格合ƈ{确定操作?br />    Witrix报表引擎的另一个特Ҏ(gu)q行期结构生成过E和l构转换q程同时q行Q因此不需要在内存中构造一个完整的报表数据对象Q大大减M内存压力。Witrix报表引擎输出的文件格式目前有html, XML格式的Word文g和XML格式的Excel文g{。每一U输出格式相当于定义了一U渲染模型,它们都是Ҏ(gu)表模型的一U展现方式。从某种E度上说q些模型的结构都是等L(fng)Q但是完成模型{换所需要的操作往往不是局域化的。例如在html的table中某一单元格具体对应哪一列是受到其他单元格的rowspan和colspan属性媄响的, 在Excel中则需要明指定列的index属性。ؓ(f)了简化运行期逻辑Q内|的报表模型必须提供一些冗余结构,从而兼容多U渲染模型?br />

canonical 2007-09-02 09:45 发表评论
]]>
静态描qC动态调?/title><link>http://m.tkk7.com/canonical/archive/2007/05/27/120327.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Sun, 27 May 2007 10:48:00 GMT</pubDate><guid>http://m.tkk7.com/canonical/archive/2007/05/27/120327.html</guid><wfw:comment>http://m.tkk7.com/canonical/comments/120327.html</wfw:comment><comments>http://m.tkk7.com/canonical/archive/2007/05/27/120327.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://m.tkk7.com/canonical/comments/commentRss/120327.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/canonical/services/trackbacks/120327.html</trackback:ping><description><![CDATA[    描述所x的是“what”Q而运行所x的是“how”。在C软g开发中Q描qC息作占的比重日益加大。甚至一U极端的們֐是把所有业务逻辑都写在各U格式的配置文g? 配置文g目前多采用xml格式Q它的优Ҏ(gu)自说明的Q属性名直接标示了其基本含义Q但是这也在一定程度上加重了命名的负担, 造成了配|文件的臃肿。因为在普通的E序语言中,可以用来传递信息的l构更加丰富Q例如参数的相对位置Q参数类? 匿名函数, 指针引用{。而一般配|文件中没有定义合适的l承Q封装等抽象机制Q很隑֦同普通程序语a那样q行有效的结构压~?br>    在很多灵zȝq型语a中,借助各式语法p?syntax sugar)可以实现描述性的q行l构, 或者可以看作是构造性的描述, 它在部分E度上消解了描述的诠释问? 不需要额外的解释器即可实现描q结构的解析. q有些类g~译理论中的语法制导译, 在动态结构组装方面具有明昄优势. <a href="http://m.tkk7.com/canonical/articles/19697.html">http://m.tkk7.com/canonical/articles/19697.html</a>. 但是独立的描qC息仍然是有着重要作用? 关键是作为元数据存在的描qC息可以以多种方式被? q可以被部分使用. 此外一些特D设计的描述文g可以很自然的汇集pȝ各个斚w的信息到同一层面加以展示,而一个通用语言无论语法如何灉|, 抽象能力如何强大, 毕竟受限于先天的l构, 要做到这一点还是不现实? <br>    在witrixq_中配|文件的设计一般是l合考虑静态描q和动态调整的需? 在设计上分成静态描q段和动态运行的initD? pȝ确保initD中的tpl代码?x)在适当的时候被调用. <br><br><br><img src ="http://m.tkk7.com/canonical/aggbug/120327.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/canonical/" target="_blank">canonical</a> 2007-05-27 18:48 <a href="http://m.tkk7.com/canonical/archive/2007/05/27/120327.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>多版本支?/title><link>http://m.tkk7.com/canonical/archive/2007/04/22/112835.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Sun, 22 Apr 2007 15:15:00 GMT</pubDate><guid>http://m.tkk7.com/canonical/archive/2007/04/22/112835.html</guid><wfw:comment>http://m.tkk7.com/canonical/comments/112835.html</wfw:comment><comments>http://m.tkk7.com/canonical/archive/2007/04/22/112835.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://m.tkk7.com/canonical/comments/commentRss/112835.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/canonical/services/trackbacks/112835.html</trackback:ping><description><![CDATA[   在商业品开发中Q如何有效的控制同一产品的多个衍生版本是一个非帔R要的问题。客L(fng)需求是多样化,差异化的。这些差异有些很,可以通过参数配置Q资源装载,skin切换{方式加以吸Ӟ而有些则要求对界面布局和程序逻辑{作大调整。Witrix开发^台在pȝ基础架构斚w为程序的客户化提供了有力的支持?br>   1. 多版本控制的关键首先在于pȝ良好的模块划分。因此Witrixq_的beans,auth-map(权限归约规则){配|文件格式都支持import/include{基的分解策?字符串资源和错误码映等支持多重定义文gQ而对于sql.xml(外部sql语句定义), meta.xml, biz.xml, hbm.xml{配|文仉用分模块动态装载机制?br>   2. 在Witrixpȝ中定义了一个特D的custom目录Q规定了一般性的覆盖规则Qcustom目录作ؓ(f)pȝ根目录的影子目录Q如果custom目录下存在同名文Ӟ则优先装载custom目录下的文g。例?如果custom目录下存?_config/my/my.biz.xml文gQ同时在根目录下也存?_config/my/my.biz.xml文g, 则实际装载的是custom目录下的实现。这里的一个关键在于只有meta.xml(元数?Qbiz.xml(BizFlow描述文g)Q?lib.xml(tpl模板?{具有一定完整性的文g才支持custom机制Q而ƈ不是所有资源都采用custom机制。如果每一个tpl文gQcss文gQjs文g{都优先从custom目录下装载,则很快就?x)出现@环引用,相对路径计算会(x)变得非常混ؕQ更重要的是我们无法定义资源删除语义?br>   3. 元数据文ӞBizFlow描述文gQPageFlow描述文g{都支持复杂的extends机制Q得我们在扩展时只需要对于系l差异部分进行描qͼ而不是大D|贝代码?br>   4. tpl模板库和sql-map机制{采用的是追加覆盖策略。例如custom目录下的ui.xml标签库文件ƈ不是直接覆盖pȝ根目录下的ui.xml文gQ而是按照标签名进行细_度的覆盖。系l编译时?x)自动检查覆盖标{所有参数要求和原标{兼容Q例如允许增加参数而不允许减少参数Q,保所有引用到原标{tpl代码仍然有效。实际上整个witrixq_多版本扩展机制的一个设计目标就是确保^Cpȝ向各个分支品的单向信息动。在具体的表C是我们随时可以拯q_ȝl覆盖到分支产品的相应目录,所有扩展实Cȝl实C持分ȝ态。当然ؓ(f)了保持设计的Ҏ(gu),pȝ中也定义了开兛_数用来有选择的蟩q一致性检查?br>  <br><img src ="http://m.tkk7.com/canonical/aggbug/112835.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/canonical/" target="_blank">canonical</a> 2007-04-22 23:15 <a href="http://m.tkk7.com/canonical/archive/2007/04/22/112835.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>PageFlow: Managed Navigationhttp://m.tkk7.com/canonical/archive/2006/11/05/79254.htmlcanonicalcanonicalSun, 05 Nov 2006 12:35:00 GMThttp://m.tkk7.com/canonical/archive/2006/11/05/79254.htmlhttp://m.tkk7.com/canonical/comments/79254.htmlhttp://m.tkk7.com/canonical/archive/2006/11/05/79254.html#Feedback7http://m.tkk7.com/canonical/comments/commentRss/79254.htmlhttp://m.tkk7.com/canonical/services/trackbacks/79254.html  /view.jsp?objectName=MyObj&objectEvent=ViewDetail&id=1
  一个url模式所对应的网个数在理论上可能是无限多的. 从单一数据值到函数是系l复杂性本质上的一U飞? Z不致在这U无限的世界中迷失方?我们昄需要对于浏览过E进行更加有效的l织,建立更加有约束性的D模型. 一U常见的D模式是在面的上Ҏ(gu)CZ条线性的D路径, 与浏览历史模型不同的? 面转换时不?
  list > view item 1 ==>  list > view item 1 > view item 2
而是
   list > view item1 ==> list > view item2
  Z支持D路径, 最单的方式是将面模型扩展Z元组[id, title, urlExpr], 其中urlExpr是动态表辑ּ, 而id是固定的? 例如 id=view, urlExpr=/view.jsp?objectName=MyObj&objectEvent=ViewDetail&id=${id}
  D路径的变化规则ؓ(f)navHistory.removeAfter(newPage.id).add(newPage)
  Zq一步约化导航\? 可以页面模型扩展ؓ(f)
  [id, title, urlExpr, group, before, beforeGroup],
  其中group定义了页面的分组, 同组的页面在D路径中相互替? 而before和beforeGroup定义了页面在D路径中的相对序. 例如对于
  [id='list' beforeGroup="detail"] [id='view' group='detail'] [id='update' group='detail']
在页面{换时, D路径变化不是
  list > view item1 ==> list > view item1 > update item1
而是
  list > view item1 ==> list > update item1
  在以上的面模型? 每一个id对应的是一个不同的面模板(面布局), 但是有时我们也需要在同一个页面布局中浏览无限分U的栏目, 此时可以页面模型扩展ؓ(f)
  [id, title, urlExpr, group, before, beforeGroup, path]
 
  以上的D模型应用于一般的web应用时还需要克服一个小的困难: 动态url的副作用. 例如/update.do?id=1&value=2q种h动作语义的url讉K直接破坏了页面的览模型Q例如现在我们不再能够按F5键刷新页面,不能通过window.location=window.location调用来刷新页面,在页面回退时我们也遇到种U困难。ؓ(f)了防止重复提交,一U常见的设计模式是分POST和GETҎ(gu)Q即通过Form POST向上提交数据Q处理完毕后通过redirect指o(h)通知览器再ơ发起GETҎ(gu)得到新的面.具体做法如下  
    /redirect_after_action.do?id=1&value=2
  在执行完action之后, 服务器调用response.sendRedirect(get_url), 通知前台览器用新的url重新取回面. q样最l我们可以确保所有页面都是可以通过url直接讉K?没有隐含的post参数),而且是可以重复访问的(无副作用因而可以反复刷?!
  另一U方式是使用ajax方式提交更新h,当ajax讉K成功? 在回调函Cq行面跌{.例如:
  new js.Ajax().setObjectName('Test')
      .setObjectEvent('Update').addForm(myForm)
      .callRemote(function(returnValue){
        window.location = '/view.jsp?id=1';
      })  
q里我们也可以根据returnValue的不同选择跌{C同页?
  在Witrixq_? ZJsplet框架我们定义了PageFlow对象, 它将可配|的D模型引入CQ意页面的l织q程? 在蟩转到一个新的页面的时? 讉Kurl如下:
  /pageflow.jsp?objectName=MyNav&objectEvent=NavToPage&_pageId=view&id=3
在重新访问历史页面的时候,只需?br /> /pageflow.jsp?objectName=MyNav&objectEvent=NavToHistoryPage&_pageId=view
  Zjsplet框架的对象化Ҏ(gu),MyNav对象在session中保持了flow的所有状态变量,不需要Q何框架上Ҏ(gu)的支持。我们可以在L面跛_pageflow, q在M时刻选择跛_pageflow, q些动作不会(x)影响到flow对象的状态。而通过objectScope的设|我们可以精l的控制flow对象的生命周期。同时基于对象化讄Q访问页面时我们只需要资源的相对名称(relative identifier), 例如对于各种不同的flow, 面id都可以叫做view, 通过_pageId=view来访问?br />  Apache软g基金?x)旗下有一个beehive目, http://beehive.apache.org/docs/1.0m1/pageflow/pageflow_overview.html, 其中也定义了所谓pageflow的概? q是始创于BEA的一Ҏ(gu)? 但是与Witrix Page Flow不同的是, Beehive Page Flow的核心概念仍然是从struts引申而出的action的概念,所谓的flow是action的连接,而不是通过资源id之间的连接。虽然beeive宣称支持各种对象injection, q且理了flow对象的生命周期,但是它ƈ没有规范出this指针q一面向对象最重要的概念之一。Witrix Page Flowx的重Ҏ(gu)已存在的面之间的有效组l? 它所描述的是某种h静态资源语义的面模板之间的关? q种兌是较松散?而不是通过action强关联的. 实际上基于Ajax技术和jsplet框架的消息\由机? 在每一个页面上都可以进行多U业务操?甚至更换面Q而不发生pageId的变? q不是所有的操作q程都需要在page flow描述中对外暴霌Ӏ另外一个比较细节化的不同之处是Beehive使用Java Annotation, 而W(xu)itrix PageFlow使用xml描述文g, q实Cpageflow的承和部分覆盖{高U构造方? 使用xml描述文g的必要性在于需要复用WebAction, 支持复杂的变换操? q成tpl模板引擎{? Annotation的方式看似简?但这U简单性同时将pȝ中的所有组分绑定到了一? 它也不允许复杂的变换操作的存? 实际上Beehive的目标ƈ不是真正支持面~制(包括面上的面操作)和页面组l的分离.

canonical 2006-11-05 20:35 发表评论
]]>
BizFlow extends CRUDhttp://m.tkk7.com/canonical/archive/2006/07/15/58366.htmlcanonicalcanonicalSat, 15 Jul 2006 14:25:00 GMThttp://m.tkk7.com/canonical/archive/2006/07/15/58366.htmlhttp://m.tkk7.com/canonical/comments/58366.htmlhttp://m.tkk7.com/canonical/archive/2006/07/15/58366.html#Feedback5http://m.tkk7.com/canonical/comments/commentRss/58366.htmlhttp://m.tkk7.com/canonical/services/trackbacks/58366.html  CRUD(Create Read Update Delete)是一般应用程序中最基础的操作,但是用户的需求却很难直接映射到CRUD操作上。例如常见的需求如?
 1. 不同的业务处理处于不同状态的业务对象:
     业务A处理状态ؓ(f)X的业务对?而业务B处理状态ؓ(f)Y的业务对?br /> 2. 业务对象处于不同状态的时候允许的操作不同:
    状态处于X的业务对象允许操作U, 而状态处于Y的业务对象允许操作V
 3. 不同的业务操作可能修改业务对象的不同属?
     操作U修改业务对象的属性P, 操作V修改业务对象的属性Q
 4. h不同权限的h能够从事的业务不?
      角色R处理业务A, 角色S处理业务B
 5. h不同权限的h即从事同一业务,所能够操作的业务对象集合也不同:
     角色R处理部门M的业务对?角色S处理部门N的业务对?
 6. h不同权限的h即可以操作同一业务对象,所能够采取的业务操作也不同:
      角色R只能q行操作U, 角色S只能q行操作V
 7. 在业务对象上执行操作之后可能造成状态变q?
      处于状态X的业务对象上执行操作U后状态变为Y

以上q些需求往往是系l中最易变的部? 而它们在概念上恰恰表Cؓ(f)对CRUD的一U限制性描q? 因此通过如下扩展我们可以定义BizFlow的概? BizFlow = CRUD + Filter. Ҏ(gu)q种观念, witrixq_中BizFlow被实Cؓ(f)DaoWebAction的一U无~扩?
   在jsplet框架中我们通过如下url模式来访问后台的CRUD操作:
   /list.jsp?objectName=MyObj&objectEvent=Query
Z实现BizFlow只需通过spring为DaoWebAction配置一个xml配置文g, 此后仍然可以通过
    /list.jsp?objectName=MyObj&objectEvent=Query
来访问后台的CRUD操作,只是后台?x)自动应用配|文件中?bizId="default", bizActionId="Query-default"{配|项.
如果我们采用如下url来访?br />    /list.jsp?objectName=MyObj&objectEvent=Query&$bizId=test&$bizActionId=test   
则后台将应用配置?bizId=manage, bizActionId=Query-test, ?br />    /list.jsp?objectName=MyObj&objectEvent=BizAction&$bizId=test&$bizActionId=test   
则对应于配置?bizId=manage, bizActionId=BizAction-test.
   应用BizFlow配置之?所有前C码都可以不做ZQ何改? 因ؓ(f)它们只是对于l定数据的展?
  
   BizFlow可以看作是CRUD加上单的程控制和权限控制所构成, 但是它与完整的工作流模型q是有着显著区别? 工作中所x的重炚w先是程实例而不是业务对象实? 在一个流E中是否存在唯一的业务对?以及(qing)业务对象的状态是否随着程{发生变化完全是一件独立的事情,它们q不属于抽象的工作流模型本n. 理论上说,一个业务对象可以同时参与多个流E? 在工作流建模中主要通过程步骤的先后顺序的U束来描qC务进E? 处于同一状态的业务对象可能处在不同的流E步骤中. 而BizFlow可以看作是状态驱动的, 当前业务步骤直接׃务对象的状态决? 在BizFlow中因角是业务对象的状?因此我们直接面对的是大量处于同一状态的不同的业务处理过E? 而workflow中往往建模的时候强调单程实例视角,而一般缺乏对于流E实例相x的描述. 现在国内很多为工作流是状态机其实是对workflow概念的一U误?
 



canonical 2006-07-15 22:25 发表评论
]]>
[导入]witrixq_中的ajax支持http://m.tkk7.com/canonical/archive/2006/02/22/32013.htmlcanonicalcanonicalWed, 22 Feb 2006 12:36:00 GMThttp://m.tkk7.com/canonical/archive/2006/02/22/32013.htmlhttp://m.tkk7.com/canonical/comments/32013.htmlhttp://m.tkk7.com/canonical/archive/2006/02/22/32013.html#Feedback0http://m.tkk7.com/canonical/comments/commentRss/32013.htmlhttp://m.tkk7.com/canonical/services/trackbacks/32013.htmlwebE序需要完?nbsp; html <--> java 之间的映,在界面越来越复杂Q越来越多变的今天,q项工作也变得越来越困难。按照列设计理论的观点Q我们应该去L一些中间的q渡步骤。在 witrixq_中,tpl模板引擎正扮演了q种中间角色。通过tpl模板我们实现了如下映\?/p>

html <--> tpl <--> java

? 意到q里html与tpl之间Q以?qing)tpl与java之间的映都不是trivial的同构关p,而是都可能存在着复杂的运过E,从而实Chtml? java映射q程中复杂性的分解与均摊。tpl与java之间的关联主要通过EL(expression language)表达式来完成Q而html与tpl的映则主要通过自定义标{?tag)机制?br> 注意到tpl所提供的中间层h独立的重大意 义,它ƈ不是臆造的或者是单的技术驱动的l果。实际上Q在web开发中除了javal构与htmll构之外q存在着W三U结构,即用L(fng)中的界面l构Q? 本来它与html所描述的结构是单的一一对应的,但是随着界面技术的发展Qhtml的描q能力逐渐被耗尽Q成Zinternet时代?汇编语言"? 现在一个简单的面片断可能对应着大量html代码Q因而׃"所写即所?的简单性。tpl通过强大的抽象能力在某种E度上恢复了E序员对于界面表 现结构的直观控制能力Qƈ在一定程度上保留了html所见即所得的Ҏ(gu)?/p>

在witrixq_中因为存在着tplq一强大的抽象层Q得我们对于ajax的支持可以采取更加灵zȝ方式?br> ajax(Asynchronous JavaScript + XML)的标准结构是
html <--> js <==> xml <==> java

? q种l构中通过xml信道的只是数据,而界面的表达逻辑与展现逻辑完全由js来控制。这U结构发展的一个极端是所有的界面展现l构都由 javascript动态构造出来,而完全׃html静态描q的特点,丧失了所见即所得的设计。与直接实现html<-->java之间 的映情늱|直接实现 html <--> js之间的映也是困隄Q尽dom模型的支持可能得js映射的难度要低于java映射?/p>

在witrixq_中ajax的方案ؓ(f)
html <--> js <==> tpl <--> java

即tpl取代了ajax标准Ҏ(gu)中xml的位|,使得映射q程的复杂性得以分散化?/p>

l合jsplet框架的拉模式Qpull mode)Q我们定义了如下ajax讉K接口
js.ajax.load({request='objectName=/@Test&objectEvent=query',tpl:'/test.tpl:partA',targetId:'testDiv'});

1?q程服务h是一D|通的http post requestQ?避免了额外的xml~码解码需求?br> 2。请求到的数据先由tpl文g来进行处理。注意到q里tpl文g的url分成两部分,前一部分是tpl文g的虚拟\径,?Q后面的部分Q即partA指出h的是该tpl文g内的partA部分Q而不是整个tpl文g?br> 3。返回的htmll果被填充到targetId所指定的html元素中?/p>

test.tpl文g的内?br> QhtmlQ?br> QbodyQ?/p>

Qtpl:define id="partA"Q?br> Qimg tpl:tag="ui:EditTable" /Q?br> Q?tpl:defineQ?/p>

Qdiv id="testDiv"Q?br> Qimg tpl:tag="ui:ViewTable" /Q?br> Q?divQ?/p>

Q?bodyQ?br> Q?htmlQ?/p> tplh强大的结构构造能力,在这里我们以非常的代h(hun)实现了tpl片断的定义,例如test.tpl中的partA部分。这里通过id讉Ktpl片断如同js中通过id来访问html片断一栗?br> 最后提一个很重要的思想Q大量零的代码片断需要集中存放,否则人的_֊?x)被耗散。一个反例就是struts中的action, 明明只干那么点事Q偏偏要占据一个单独的java文gQ占据大量单独的配置条目Q最l给E序员带来很大的困扰?img src ="http://m.tkk7.com/canonical/aggbug/32013.html" width = "1" height = "1" />

canonical 2006-02-22 20:36 发表评论
]]>
[导入]E序中的l构表达http://m.tkk7.com/canonical/archive/2005/12/28/25798.htmlcanonicalcanonicalWed, 28 Dec 2005 14:49:00 GMThttp://m.tkk7.com/canonical/archive/2005/12/28/25798.htmlhttp://m.tkk7.com/canonical/comments/25798.htmlhttp://m.tkk7.com/canonical/archive/2005/12/28/25798.html#Feedback0http://m.tkk7.com/canonical/comments/commentRss/25798.htmlhttp://m.tkk7.com/canonical/services/trackbacks/25798.html  循环l构是imperative language的重要组成部分,一般也是程序中比较难以理解的部分。特别是没有软g技术背景的朋友Q明昑֯于@环的理解力较弱。在Von  Neumann体系l构中,赋D句是必须的,因而引Z存储概念Q也引入了时间概念,因ؓ(f)我们可以区分值前和赋值后的时刅R引入时间之后,本质性的 影响是程序串行化Q而强q我们从q行思考{入串行处理。很多时候这是一U不自然的情况,在我们的自然思维中,我们看到的或惛_的也许只是一l静态结构,? 在程序中表达的时候却往往不可避免的需要引入一个动态过E。而我们控制动态结构的能力L不的。最q对于函数式语言?qing)处理风格的来强烈的要求可能? 从侧面反映了大家对这U结构失配的不满?br>   但是串行思维毫无疑问也是我们正常思维模式的一部分Q当然这U思维模式在多大程度上是因为Von Neumann 体系造成的,也是个很有趣的问题)。例如在面渲染的时候,我们可能希望预先把所有用到的数据都{载到内存中,赋予不同的变量名Q然后在面模板中我们只 要知道如何把q些数据变量表现出来可以了。先做完A再做BQ这是分层的思想Q也是典型的串行思维。而基于数据进行处理,也是Von Nenuman体系的基本思想。但是如果处处要求预先计ƈ赋|往往增加了很多额外的步骤(glue code)Qƈ且增大了对内存(计算I间Q的需求。分层之后,q存在着一个各个层ơ之间结构匹配的l护问题?br>   面向对象在结构表达方面是一U? 巨大的进步。经q多q的发展Q我们在表达静态结构关pL面已l是驾轻q了。通过属性关联,我们可以沿着对象图进行结构遍历。如果用成员函敎ͼ在这U遍 历过E中q可以包Ҏ(gu)多的动态特性。而在数据持久化方面,ORM的盛行也在一定程度上证明了对象图的有效性。用对象图可以大大降低对赋D句的需求,? M明确建模的压力(每一ơ赋值都要求着一个明的变量名,一个概念)Q也~解了Von Neuman体系l构的束~。例如,我们不再需?br> var user = loadUser(userId);
  var userOrgnization = loadOrgnization(user.orgId);
  var userOrgnizationName = userOrgnization.name
而是直接使用  user.orgnization.name

    目前面向对象所表达的大多数l构q是Z数据语义的,而我们对于函数等高阶l构的控制能力仍然较弱。设计模式在q方面提供了一些经验,但还是远q不够的? 在我们经验不多的时候,我们需要依赖于明确的实体数据,而在我们的理解逐步深入之后我们可以通过Visitor, Iterator{模式支撑v整个l构。高阶结构比低阶l构难以控制Q一斚w是因为动态性本w比静态性难以理解,另一斚w函数对信息的使用和流动是一U主 动约?如果U束的不正确Q会(x)造成l构的失效。而数据的使用是完全开攄Q很多决定都可以延迟C用时d定。当Ӟ开放性带来的问题也早׃所周知了:(x) 不受限制的用将D无法控制的困境。在基础的数据层装斚wQ一般我q不提倡大量用domain model似的h丰富语义的数据对象。因为数据是׃n的,应该存在一个开攄数据层,在其上可以徏立业务对象。؜杂在一起会(x)限制pȝ的演化?/font>

canonical 2005-12-28 22:49 发表评论
]]>
[导入]IVarValueSet: Map语义的扩?/title><link>http://m.tkk7.com/canonical/archive/2005/12/28/25792.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Wed, 28 Dec 2005 14:22:00 GMT</pubDate><guid>http://m.tkk7.com/canonical/archive/2005/12/28/25792.html</guid><wfw:comment>http://m.tkk7.com/canonical/comments/25792.html</wfw:comment><comments>http://m.tkk7.com/canonical/archive/2005/12/28/25792.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/canonical/comments/commentRss/25792.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/canonical/services/trackbacks/25792.html</trackback:ping><description><![CDATA[<p><font color="#000000" size="3"> </font>  关系数据库提供的是集合存储模型, query(fields, condition) ==> list of records, 可以从条仉合映到记录集合?br> 当condition退化ؓ(f)单一的key, 而fields采用默认值的时候,我们退化到Map语义, 从key对象映射到value对象Q而不是从集合映射到集合?br> ? 多时候我们只需要这U简单Map语义的存储模型,例如用户偏好讄的存储。在q种受限的模型下我们也可以更直接的实现cache支持。如果我们希望在 Map的基上稍微扩展一些集合操作的Ҏ(gu),可以通过key的结构扩展来实现。即规定key采用cMurl格式的字W串Q实现keyI间的树(wi)形结构。在 witrixq_中,q种?wi)Şl构的映关p通过IVarValueSet接口来实现?br>  interface IVarValueSet{<br>      IVariant getVar(String name);</p>      // 得到前缀为prefix的所有变量构成的子集合,注意q里自然退化的特点<br>      IVarValueSet getSubSet(String prefix);<br>   }<br> 变量名的格式规定为 a.b.c 或?a/b/c. q种变量l构的组l和划分方式其实与JBoss目中的TreeCachel构cM?img src ="http://m.tkk7.com/canonical/aggbug/25792.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/canonical/" target="_blank">canonical</a> 2005-12-28 22:22 <a href="http://m.tkk7.com/canonical/archive/2005/12/28/25792.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]validate: javascript 客户端验证框?/title><link>http://m.tkk7.com/canonical/archive/2005/12/12/23564.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Mon, 12 Dec 2005 14:26:00 GMT</pubDate><guid>http://m.tkk7.com/canonical/archive/2005/12/12/23564.html</guid><wfw:comment>http://m.tkk7.com/canonical/comments/23564.html</wfw:comment><comments>http://m.tkk7.com/canonical/archive/2005/12/12/23564.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/canonical/comments/commentRss/23564.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/canonical/services/trackbacks/23564.html</trackback:ping><description><![CDATA[<p>    在witrixq_中,validate.js提供了完整的客户端输入校验框架。其基本思想是ؓ(f)每个输入控g指定验证函数Qvalidator属性)Q在提交Form的时候自动调用该验证函数卛_?br> <form action="test.jsp"><br> <input type="text" name="userName" validator="js.validate.checkNotEmpty(value,'用户?)" /><br> <input type="button" value="submit" onclick="js.validate.submitForm(this.form)" /><br> </form><br>     witrixq_的一个基本设计原则是模块的独立性,不仅各个模块之间的耦合很少Q我们还量避免使用配置文g。与struts{web框架不同Q? witrix的输入校验不依赖于外部配|文Ӟ可以完全独立的用。虽然jsplet框架也提供了服务器端校验的支持,但在实际使用q程中却很少使用。客 L(fng)校验提供了更好的用户体验。而如果我们需要进一步确保业务逻辑的稳定性,例如避免用户伪造客L(fng)urlhQ数据校验需要在业务逻辑对象层进行而不? 是在解析用户h的时候。针Ҏ(gu)个form所写的配置文g有很多不方便的地方,例如witrixq_支持从数据库描述文g直接生成操作界面的快速开发,? 验规则在数据描述文g中指定,而同一个字D可能在多个界面中出玎ͼ如果针对Form写校验配|文Ӟ׃(x)出现冗余Q而难以保证结构的同步。实际上Q一个结 构在界面上表Cơ,又在校验配置文g中表Cơ,必然会(x)出现同步问题Q解决的Ҏ(gu)是面向对象设计中的对象化,局部化Q而不是一个个分离的处理层?/p>     很多客户端的校验框架使用的是一个万能的校验函数Q通过参数不同来实C同校验。例?br> <input type="text" name="userName" validateType="required" /><br> q种方式的扩展性不好。正如面向对象设计中的通常做法Q我们通过使用回调函数Q虚拟函敎ͼ来实现可扩展的设计?img src ="http://m.tkk7.com/canonical/aggbug/23564.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/canonical/" target="_blank">canonical</a> 2005-12-12 22:26 <a href="http://m.tkk7.com/canonical/archive/2005/12/12/23564.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]tpl与FreeMarker的标{֯?/title><link>http://m.tkk7.com/canonical/archive/2005/12/12/23560.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Mon, 12 Dec 2005 14:18:00 GMT</pubDate><guid>http://m.tkk7.com/canonical/archive/2005/12/12/23560.html</guid><wfw:comment>http://m.tkk7.com/canonical/comments/23560.html</wfw:comment><comments>http://m.tkk7.com/canonical/archive/2005/12/12/23560.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://m.tkk7.com/canonical/comments/commentRss/23560.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/canonical/services/trackbacks/23560.html</trackback:ping><description><![CDATA[<p>witrixq_中的tpl模板技术是一U通用的xml动态标{技术,不仅可以用于文本生成Q而且可以用于M需要动态标{地方Q例如工作流引擎 的配|和执行脚本。tpl模板引擎采用的不是jsp tag的标准机Ӟ而是重新设计q实现的。在开发的后期Q因为jstl标准出现Q我们对标签的命名作了一定的修改Q以量W合标准的调用接口。tpl模板 语言完全W合xml规范Q其标签定义都是完全独立开发的。在开发tpl的时候,我们甚至没有看到McM于c:forEach和c:if的标{设计。但? 我们发现Qtpl的动态处理功能与jstl虽然命名不同Q但是基本是{h(hun)的,所以修Ҏ(gu)非常直接的过E?</p> <p>FreeMarker是一U流 行的文本模板语言Q其语法cM于xml tagQ但是命名规则不同。这实在是一Uo(h)解的设计。有意思的是,我们发现tpl的功能集也包含了FreeMarker的功能集。这实际上表明了一? 事情Qxml动态标{֭在一些必然的功能需求,无论是jsp tag, FreeMarkerq是tpl, 所不同的只是表现Ş式而已。但q种表现形式的差异却又造成了实际功能上的巨大差异?</p> <p>tpl与FreeMarker具体Ҏ(gu)如下?</p> <p>宏定?br>Q?macro greet personQ?br>Qfont size="+2"QHello ${person}Q?fontQ?br>Q?#macroQ]]Q?/p> <p>Qc:lib namespace="test"Q?br>Qgreet demandArgs="person"Q?br>Qfont size="+2"QHello ${person}Q?fontQ?br>Q?greetQ?br>Q?c:libQ?/p> <p>tplh更加强大的变量域控制手段Q可以通过importVars参数来指定是否用调用环境中的变量作为缺省参数。另一斚wQtplh更加灉|的参数校验规则,可以通过demandArgs, otherArgs{参数来指定对自定义标签参数的校验规则?<br>调用?br>Q@greet person="Fred" /Q?<br>Qtest:greet person="Fred" /Q?/p> <p>嵌套内容<br>Q?macro borderQ?br>Qtable border="4" cellspacing="0" cellpadding="4"Q<trQ<tdQ?br>Q?nestedQ?br>Q?nestedQ?<br>Q?trQ</tdQ</tableQ?br>Q?#macroQ?<br>Qc:lib namespace="test"Q?br>Qborder type="bodyTag"Q?br>Qtable border="4" cellspacing="0" cellpadding="4"Q<trQ<tdQ?br>Qcp:compile src="${tagBody}" /Q?br>Q?trQ</tdQ</tableQ?br>Q?borderQ?br>Q?c:libQ?/p> <p>tpl的<cp:compileQ指令在执行时可以指定xslt参数Q从而在~译tagBody之前应用xslt变换?<br>复杂嵌套<br>与FreeMark一?嵌套内容可以是复杂内?/p> <p>Q@borderQ?br>QulQ?br>Q@do_thriceQ?br>QliQ<@greet person="Joe"/Q?br>Q?a>/@do_thrice</a>Q?br>Q?ulQ?br>Q?a>/@border</a>Q?<br>Qtest:borderQ?br>QulQ?br>Qtest:do_thriceQ?br>QliQ<test:greet person="Joe" /Q</liQ?br>Q?test:do_thriceQ?br>Q?ulQ?br>Q?test:borderQ?/p> <p>导入?br>Q?import "/lib/my_test.ftl" as myQ?<br>Qc:lib src="/lib/my_test.ftl" namespace="my" /Q?/p> <p>创徏或替代变?br>Q?assign mail="<a href="mailto:jsmith@other.com">jsmith@other.com</a>" /Q?<br>Qc:set var="mail" value="<a href="mailto:jsmith@other.com">jsmith@other.com</a>" default="xx"/Q?/p> <p>判断<br>Q?if animals.python.price Q?animals.elephant.priceQ?br>Pythons are cheaper than elephants today.<br>Q?#ifQ?<br>Qc:if test="${lt(animals.python.price,animals.elephant.price)}"Q?br>Pythons are cheaper than elephants today.<br>Q?c:ifQ?/p> <p>tpl因ؓ(f)是xml语法Q算术操作符Q和Q必{义后才能使用Q用v来很不方便,因而最l决定tpl不支持操作符Q通过lt(), gt(){函数来实现功能?<br>循环<br>Q?list animals as beingQ?br>QtrQ<tdQ?{being.name}QtdQ?{being.price} Euros<br>Q?#listQ?<br>Qc:forEach var="being" items="${animals}" Q?br>QtrQ<tdQ?{being.name}QtdQ?{being.price} Euros<br>Q?c:forEachQ?/p> <p>tpl提供Qc:tileQ等多种循环方式 <br>include指o(h)<br>Q?include "/copyright_footer.html"Q?<br>Qc:include src="/copyright_footer.html" /Q?/p> <p>tpl强大的模板功能加上jsplet框架面向对象的能力,使得我们可以L的封装复杂的界面lg。而且q种装能力q不需要Tapestry那种复杂的配|文件。tpl对portal应用的支持也是一个自然的发展q程?/p> <img src ="http://m.tkk7.com/canonical/aggbug/23560.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/canonical/" target="_blank">canonical</a> 2005-12-12 22:18 <a href="http://m.tkk7.com/canonical/archive/2005/12/12/23560.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]Exceptions: l一异常处理http://m.tkk7.com/canonical/archive/2005/12/02/22302.htmlcanonicalcanonicalFri, 02 Dec 2005 15:00:00 GMThttp://m.tkk7.com/canonical/archive/2005/12/02/22302.htmlhttp://m.tkk7.com/canonical/comments/22302.htmlhttp://m.tkk7.com/canonical/archive/2005/12/02/22302.html#Feedback0http://m.tkk7.com/canonical/comments/commentRss/22302.htmlhttp://m.tkk7.com/canonical/services/trackbacks/22302.html    在witrixq_中,异常处理没有采用java语法支持的checked exception, 也不提倡用自定义的异常类Q? 而是定义了少数几个RuntimeException基类Q一般是CommonException(RuntimeException的派生类)?br>     在我自己的经验中Qchecked exception从未发挥q实质性的作用。checked exception在某U程度上破坏了封装性原则。我们一般不?x)在最l的_度上处理异常,而是在某个统一的模块节点处q行。如果用checked exception, 则从最底层的调用到具体异常处理层的整个调用堆栈上的函数都必L标记自׃处理该异常,q是完全不必要的负担。这U细_度上的负担往往程序员引导? 错误的方向上去,例如~写catch块直接捕获异?br>   try{
     ...
  }catch(MyException e){
     e.printStackTrace();
  }
在witrixq_中通过包装cLchecked exception包装为RuntimeException, 而且除了在最l代码处理模块决不屏蔽异常?br>  try{
    ...
 }catch(IOException e){
 throw Exceptions.source(e); // 此时?x)自动trace异常堆栈?qing)异常消?br>  }

Q后来看到Bruce Eckel的文?a >Does Java need Checked ExceptionQ发现大家在对待checked exception的态度上倒是心有戚戚焉。)

     一般用自定义的异常类g是要类名作为错误返回码使用Q利用java~译器可以做所谓的强类型检查,q实在是一U概念上的浪贏V毕竟创建ƈl护一? javac还是有一定的代h(hun)的,特别是错误码l常变动而且数量不菲。实际上Qjavacd的设计中也是量重用已有的异常类Q例如整个jdbc包只抛出 SQLException异常Qxml包只抛出SAXException异常?/p>

     使用异常Q常见的Ҏ(gu)是抛Z个字W串消息Q例?throw new MyException("the object manager does not contains the object :" + objectName);
q种做法的主要问题是Q字W串异常消息无法q行q一步的处理Q因而只能直接显C给最l用Pq一斚w限制了错误显C的格式和方式,另一斚w也不利于E序的多语言支持?br>      witrixq_中抛出异常的标准Ҏ(gu)?
 throw Exceptions.code(errorCode).param(paramValue).param(paramName,paramValue);
例如
    throw Exceptions.code("web.CAN_err_missing_object_in_manager").param(objectName).param(objectManager);

class Exceptions{
    public static CommonException code(String errorCode){
  return new CommonException(code);
 }
}

class CommonException extends RuntimeException{
 public CommonException param(Object paramValue){
  ...
  return this;
 }
}
      Exceptions规定只用规范格式的错误码而不是Q意格式的异常消息。这样在捕获异常之后Q就可以Ҏ(gu)错误码和当时的语aLocale讄来决定最l显C的消息格式?br>       同时CommonException采用式设计来支持Q意数量的自定义参数。这一斚w减少了自定义异常cȝ需求,另一斚w也避免了参C错误码؜合的們֐Q即我们׃?x)們֐?
使用 throw Exceptions.code("the object manager does not contains the object :" + objectName);



canonical 2005-12-02 23:00 发表评论
]]>
tpl标签定义http://m.tkk7.com/canonical/archive/2005/11/27/21580.htmlcanonicalcanonicalSun, 27 Nov 2005 12:32:00 GMThttp://m.tkk7.com/canonical/archive/2005/11/27/21580.htmlhttp://m.tkk7.com/canonical/comments/21580.htmlhttp://m.tkk7.com/canonical/archive/2005/11/27/21580.html#Feedback0http://m.tkk7.com/canonical/comments/commentRss/21580.htmlhttp://m.tkk7.com/canonical/services/trackbacks/21580.html     <标签库名U?gt;
        <自定义标{֐ demandArgs="argA, argB"
            importVars="varA, varB"
            otherArgs="optionalArgA, optionalArgB" localScope="trueOrFalse" >

            自定义标{内容, 可以是Q何tpl代码
        </自定义标{֐>

    </标签库名U?gt;

    demandArgs中指定调用时必须l定的参数的名称列表, importVars指定从调用环境中导入的变量的名称列表,otherArgs指定可选参数的名称列表. demandArgs, importVars和otherArgsq三者的集合包含了所有该自定义标{能够接受的参数. tpl~译器会(x)查这些调用规则是否被满. 在运行的时? 未指定的可选参C(x)被初始化为null.

    在调用时明确的指定的变量g(x)覆盖importVars导入的变量? 例如
    <c:set var="varA" value="a" />
    <MyLib:自定义标{֐ /> // Ҏ(gu)importVars讑֮, 在此标签内varA的gؓ(f)a
    <MyLib:自定义标{֐ varA="b" /> // args讑֮?x)覆盖importVars导入的?因此在标{ֆ?varA的gؓ(f)b
    // 调用标签完成? varA的值恢复ؓ(f)a

    tpl中的参数声明方式是非常简化的,但是它仍然保留了最关键的信?变量名称. 而在q型的Expresison Language? 变量cd本来׃重要. 与jsp tag中的标签声明作个Ҏ(gu).
     <tag>
        <name>template</name>
        <tagclass>edu.thu.web.tags.TemplateTag</tagclass>
        <bodycontent>JSP</bodycontent>
        <attribute>
            <name>src</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
    jsp tagq种标签声明方式非常冗长, 提供的有效信息密度很? 而相对于tpl标签的声明方式所能够提供的附加信息也没有很大的意? q种设计上的问题也深q影响到JSF{派生技?

    localScope参数指定了此自定义标{是否具有局部变量环? 如果为true(~省?,  则调用此标签的时候会(x)自动q行变量压栈处理, 在标{ֆ部无法访问参数列表之外的变量, q行中所产生的(f)时变量也不会(x)影响到外部环? tpl中的变量堆栈与webwork的ValueStack机制是有一些差异的. webwork2中的ognl语言在访问OgnlValueStack中的对象的时候缺省采用的是一U递归查找机制, 卛_当前环境中找不到对象, 则自动查找上一层环境中的变? tpl中的标签l构可以多重嵌套, 产生非常复杂的结? 所以缺省情况下tpl标签采用了类g函数堆栈的设? 在子标签中的代码一般情况下是无法访问父标签环境中的变量?除非指定了localScope参数为true). localScope支持与importVars机制相结合之? 我们可以实现比OgnlValueStack更加灉|也更加稳健的变量讉K{略.  



canonical 2005-11-27 20:32 发表评论
]]>
tpl标签l构http://m.tkk7.com/canonical/archive/2005/11/22/21045.htmlcanonicalcanonicalTue, 22 Nov 2005 15:09:00 GMThttp://m.tkk7.com/canonical/archive/2005/11/22/21045.htmlhttp://m.tkk7.com/canonical/comments/21045.htmlhttp://m.tkk7.com/canonical/archive/2005/11/22/21045.html#Feedback0http://m.tkk7.com/canonical/comments/commentRss/21045.htmlhttp://m.tkk7.com/canonical/services/trackbacks/21045.html     tpl自定义标{基本l构如下Q?br>     <Namespace:TagName tpl:tag="realTagName"
        tpl:noborder="${booleanExprInCompileContext}"
        tpl:ignore="${booleanExprInCompileContext}"
        attrName="stringOrExpression" cp:attributeInCompileContext="atringOrExpression"
        OtherNamespace:OtherAttrName="stringOrExpression"
        >
        bodyContent
    </NameSpace:TagName>
    自定义标{L处在某一名字I间中, tpl名字I间中的属性由tpl~译器负责进行解析ƈ处理, 而cp名字I间中的属性在~译期能够访问,其他名字I间的属性被完全忽略Q? 一般只有decorator?x)识别这些属?例如cache:timeout).所有无名字I间的属性都相当于是自定义标{调用参数Q在标签q行的时? 可以在标{ֆ部访问到?br>     tpl通过对namespace的用, 避免了系l属? decorator属性与普通标{ֱ性之间的怺q扰Q?q与JSF和Tapestry都是不同的?br>     tpl:tag属性指定此标签在编译时对应的真实标{֐, 即编译期?x)识别RealTagName而不是Namespace:TagName。tpl:noborder为true的时候相当于是直接编? bodyContent, 例如用来在编译期控制是否在界面上使用某种Ҏ(gu)?br>     tpl:ignore为true的时候,此标{ְ被忽略而不?x)被~译?br>     bodyContent在编译期成ؓ(f)tagBody变量, p定义标签自己军_如何处理, q种方式比FreeMarker?lt;#nested>机制要灵zd强大的多. 例如在标{ֆ部我们可以?lt;cp:compile src="${tagBody}" /> q等价于 FreeMarker?lt;#nested>. 也可以?br>     <cp:compile src="${tagBody.existingChild('header')}" />从bodyContent中取出header子节? 甚至我们可以对tagBodyq行加工之后再进行编?

canonical 2005-11-22 23:09 发表评论
]]>
[导入]meta-enhanced Maphttp://m.tkk7.com/canonical/archive/2005/11/22/21010.htmlcanonicalcanonicalTue, 22 Nov 2005 09:53:00 GMThttp://m.tkk7.com/canonical/archive/2005/11/22/21010.htmlhttp://m.tkk7.com/canonical/comments/21010.htmlhttp://m.tkk7.com/canonical/archive/2005/11/22/21010.html#Feedback0http://m.tkk7.com/canonical/comments/commentRss/21010.htmlhttp://m.tkk7.com/canonical/services/trackbacks/21010.html      实际上,在ORM软g中用的bean基本上与一个MapcMQ只是它hjava Class所提供的元数据Q而访问数据时又必通过get/setҎ(gu)Q因而在q些Ҏ(gu)中能够根据元数据动态的作出响应。在witrixq_的统一数据? 问框架中主要ZMap{通用数据cdQ而不是个性化的bean。ؓ(f)了得Maph与bean一L(fng)动态响应能力,只需要加入meta的支持即可?br> interface IExMap extends Map{
     IMapChecker getChecker();
  Map getModifications();
  ...
}
在get/set之前可以通过IMapChecker来实现动态处理,对Map中数据所作的修改也可以记录下?img src ="http://m.tkk7.com/canonical/aggbug/21010.html" width = "1" height = "1" />

canonical 2005-11-22 17:53 发表评论
]]>
延迟加蝲的数据集?/title><link>http://m.tkk7.com/canonical/archive/2005/11/19/20545.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Sat, 19 Nov 2005 03:04:00 GMT</pubDate><guid>http://m.tkk7.com/canonical/archive/2005/11/19/20545.html</guid><wfw:comment>http://m.tkk7.com/canonical/comments/20545.html</wfw:comment><comments>http://m.tkk7.com/canonical/archive/2005/11/19/20545.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/canonical/comments/commentRss/20545.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/canonical/services/trackbacks/20545.html</trackback:ping><description><![CDATA[     在程序中需要返回一个数据集合的时? 应该量选用标准的Java集合cL?例如List, Map{? 有时也见到有人选择q回Iterator对象, 一般情况下q不是很好的选择. Iterator对象的功能有? 而且存在一U即时消费的特点, 我们一般不能把一个Iterator保存h留待以后使用. 而且JDK提供的集合类也不能从Iterator直接构造出?例如没有 new ArrayList(myIterator), q样为数据复刉成一定的困难. <br>     Iterator在理Z的好处之一是可以支持gq加载数? 但是实现h比较J琐而且单条加蝲也是比较低效? 在witrixq_中如果需要gq加载数据集? 我一般选择使用IPageViewer接口<br>        interface IPageViewer{<br>            public List getAll();<br>            public int getTotalCount();<br>            public List listPage(int startPos, int maxCount);<br>        }<br>     IPageViewer通过getAll()可以转换到List, 也可以通过 new Pager(pageViewer,pageSize).itemIterator()得到单条数据的Iterator, 其内部采用分加载模? 搜烦引擎q回的结果和数据库查询的l果都可以用这一接口. <img src ="http://m.tkk7.com/canonical/aggbug/20545.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/canonical/" target="_blank">canonical</a> 2005-11-19 11:04 <a href="http://m.tkk7.com/canonical/archive/2005/11/19/20545.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]交叉表:(x)q面表的q置http://m.tkk7.com/canonical/archive/2005/11/19/20543.htmlcanonicalcanonicalSat, 19 Nov 2005 03:02:00 GMThttp://m.tkk7.com/canonical/archive/2005/11/19/20543.htmlhttp://m.tkk7.com/canonical/comments/20543.htmlhttp://m.tkk7.com/canonical/archive/2005/11/19/20543.html#Feedback0http://m.tkk7.com/canonical/comments/commentRss/20543.htmlhttp://m.tkk7.com/canonical/services/trackbacks/20543.html交叉?Cross Table)的基本特Ҏ(gu)h横纵两个自由延展的维度,而^面表l构只有一个可延展的维度,因ؓ(f)q面表的列名和列数是定的。例如,地区的品销售数量,在^面表中表达ؓ(f)
district_id product_id sell_num
如果表现Z叉表Q则?br>            productA  productB
districtA   sellNum   sellNum
districtB   sellNum   sellNum
q种l构上的失配需要通过E序逻辑来进行调整?/p>

注意到^面表l构只具有一个可延展的维度,而join可以看作是该l度上的q接操作。因此我们可以将交叉表看作是多个单^面表l构q置的结果。即分解?br> A:        
           productA
districtA   sellNum
districtB   sellNum

B:
           productB
districtA   sellNum
districtB   sellNum

横向l度的扩展在E序中表达?/p>

SqlInfol构装了这U简单^面表的分解片断?br> class SqlInfo{
    List fieldNames;
    SQL sql;
    String keyField;
}

我们在程序中通过JoinBuilder来实现横向维度的构?br> JoinBuilder.begin(sqlInfoA)
           .join(sqlInfB)
           .leftJoin(sqlInfoC)
           .end();
生成的sql语句CZ如下
select sqlInfoA.fieldNames, sqlInfoB.fieldNames
from sqlInfoA.sql join sqlInfoB.sql
on sqlInfoA.keyField = sqlInfoB.keyField



canonical 2005-11-19 11:02 发表评论
]]>
[导入]Exportor: Visitor模式http://m.tkk7.com/canonical/archive/2005/11/19/20542.htmlcanonicalcanonicalSat, 19 Nov 2005 03:01:00 GMThttp://m.tkk7.com/canonical/archive/2005/11/19/20542.htmlhttp://m.tkk7.com/canonical/comments/20542.htmlhttp://m.tkk7.com/canonical/archive/2005/11/19/20542.html#Feedback0http://m.tkk7.com/canonical/comments/commentRss/20542.htmlhttp://m.tkk7.com/canonical/services/trackbacks/20542.html数据导出的功能大致可以分解ؓ(f)三个部分: 1. 从数据源d一条记?2. 一条记录导Zؓ(f)指定格式 3. 循环调用1?
? 先我们需要一U机制来对外暴露数据源(一UContainerQ中的数据,Iterator模式恰能满要求。其ơ,我们需要一U机制来对一pd数据q行 处理Q这对应于Visitor模式。第三,在组合Iterator模式和Visitor模式的处理过E中Q我们需要表辑ևq面表数据集的基本特征?br> 在witrixq_中,q面表数据导出和转换通过TablePageProcessor对象来完成,
class TablePageProcessor{
 IPageViewer viewer;

 public Object process(ITableVisitor visitor){
  Pager pager = new Pager(viewer, pageSize);
  Iterator it = pager.itemIterator();
  visitor.visitBegin(headers);
  while(it.hasNext()){
   Object row = it.next();
   if(!visitor.visitRow(row))
    break;
  }
  return visitor.visitEnd();
 }
}

interface ITableVisitor{
 void visitBegin(List headers);
 boolean visitRow(Object row);
 Object visitEnd();
}

IPageViewer是暴露^面表数据的标准接口,它通过Pager对象的包装之后可以提供各UIterator.
ITableVisitor体现了^面表数据的基本特? header + 一pdrow, 存在数据边界(起始与终?
TablePageProcessor固化了IPageViewer和ITableVisitor的组合过E?br> ITableVisitor可以有多U实玎ͼ例如CSVBuilder, ExcelBuilder{等?img src ="http://m.tkk7.com/canonical/aggbug/20542.html" width = "1" height = "1" />

canonical 2005-11-19 11:01 发表评论
]]>
[导入]Pager: Bridge模式http://m.tkk7.com/canonical/archive/2005/11/19/20541.htmlcanonicalcanonicalSat, 19 Nov 2005 03:00:00 GMThttp://m.tkk7.com/canonical/archive/2005/11/19/20541.htmlhttp://m.tkk7.com/canonical/comments/20541.htmlhttp://m.tkk7.com/canonical/archive/2005/11/19/20541.html#Feedback0http://m.tkk7.com/canonical/comments/commentRss/20541.htmlhttp://m.tkk7.com/canonical/services/trackbacks/20541.html分页的功能由两部分组成:(x)取数据和计算分页。其中取数据的功能由IPageViewer接口实现
interface IPageViewer{
 int getTotalCount();
 List getAll();
 int listPage(int startPos, int maxCount);
}
Pager是用戯用时的接?br> class Pager{
 public List getAll(){}
 public List listPage(){}
 public int getPageCount(){}
 public int getPageSize(){}
 public int getCurrentPage(){}
 ...
}
Pager使用IPageViewer作ؓ(f)数据供体Q自w仅提供分页计算的功能。在witrixq_? IPageViewer是表格数据的标准列D方式Q因ZList接口相比QIPageViewer容许部分加蝲?br> IPageViewer 可以有多U实玎ͼ如ListPageViewer, XmlPageViewer, ExcelPageViewer, DbTablePageViewer{。一般情况下Pager提供的功能已l够了Q特D情况下可以通过l承来扩展。例如卡片浏览和分页览模式之间的互 相切换通过zcItemPager来实现?br>



canonical 2005-11-19 11:00 发表评论
]]>
[导入]TreeNode:长程兌http://m.tkk7.com/canonical/archive/2005/11/19/20540.htmlcanonicalcanonicalSat, 19 Nov 2005 02:59:00 GMThttp://m.tkk7.com/canonical/archive/2005/11/19/20540.htmlhttp://m.tkk7.com/canonical/comments/20540.htmlhttp://m.tkk7.com/canonical/archive/2005/11/19/20540.html#Feedback0http://m.tkk7.com/canonical/comments/commentRss/20540.htmlhttp://m.tkk7.com/canonical/services/trackbacks/20540.htmljava中最常用的数据结构类型是Map和ListQ? 它们也是Container的两U基本模式,一个是Ҏ(gu)特征值定位,一个是Ҏ(gu)地址定位? 它们共同的一个特征是表达了数据之间的直接的,短程的一U相x。另一U常见的数据l构Tree则表达了数据之间的一U长E的兌Q根节点与其所有层ơ上 的子节点之间都存在着兌?文gpȝQ组l机? XML文档{都可以对应为Tree数据l构。在描述?wi)Şl构的时候,我们l常使用XML文gQ? 但是XML文g在程序中操纵hq不方便Q这其中的一个重要原因是XML是面向文档的Q即操纵XML的APIq回的和使用的都只能是文本字W串Q而不能直 接用程序中常见的其他数据结构。在witrixq_中操UTreel构的标准接口是TreeNodec,它的设计是面向应用的Q即节点的属性gؓ(f) Objectcd而不是Stringcd?/p>

Tree׃部分l成: 属性,| 子节?/p>

class TreeNode implements IVariant{
 List getChildren();

 int getChildCount();
 TreeNode child(int index);

 /** 当name对应的节点不存在时将?x)自动创节?*/
 TreeNode child(String name);

    /** 当name对应的节点不存在时返回null */
 TreeNode existingChild(String name);

 Map getAttributes();
 IVariant attribute(String name);
 void setAttribute(String name, Object attrValue);
}

TreeNode.attribute(name)q回的是IVariant接口Q例?br> boolean defaultValue = true;
boolean b = node.child("subA").attribute("attrB").booleanValue(defaultValue);

TreeNode本n也是IVariant接口的一个实?例如
int i = ode.intValue();

通过使用IVariant接口Q我们实C强类型的java语言与弱cd的xml文本之间的自然{换,在{换过E中q可以指定缺省|q些都极大的化了实际应用时的~码量?img src ="http://m.tkk7.com/canonical/aggbug/20540.html" width = "1" height = "1" />

canonical 2005-11-19 10:59 发表评论
]]>
[导入]Query:l构化查?/title><link>http://m.tkk7.com/canonical/archive/2005/11/19/20539.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Sat, 19 Nov 2005 02:58:00 GMT</pubDate><guid>http://m.tkk7.com/canonical/archive/2005/11/19/20539.html</guid><wfw:comment>http://m.tkk7.com/canonical/comments/20539.html</wfw:comment><comments>http://m.tkk7.com/canonical/archive/2005/11/19/20539.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/canonical/comments/commentRss/20539.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/canonical/services/trackbacks/20539.html</trackback:ping><description><![CDATA[   CRUD(Create, Read,Update, Delete)操作中最隑֤理的是查询。因为查询L多样化的Q如果每个特定查询调用都~制一个对象方法,则维护量太大且扩展性很差。如果编制一个通用? 查询接口Q一般的做法是直接以SQL文本作ؓ(f)参数Q但q样几乎׃装的意义。这里的核心问题是Query本n是复杂的Q我们应该将它对象化Z? c,在程序中控制Query的结构,而一个文本对象与一个复杂的Javal构对象的差异就在于对于文本对象我们很难有什么假定,因而在E序中也很难~制? 用的E序对其q行处理Q一般只能对它进行传递。实际上Q文本中描述的结构存在于javaE序之外!当然Q我们可以利用Parser来重新发现这U结构,? 最Ҏ(gu)使用的Parser是xml parser了,所以我们应该将Query的结构徏立在xml描述的基上?br> edu.thu.search.Querycȝ接体C对主题域的通用查询条g?Ҏ(gu)我对数据仓库模型的描q?<br> class Query{<br>     List getFields();<br>  TreeNode getCondition();<br> }<br> ? 询条件主要通过TreeNodeq行昑ּ建模Q得程序有可能对它q行q一步的处理。例如,在DataSource处理Query之前Q权限配|模块可? 附加约束直接追加到现有查询条g之后Q实现对数据权限的行U控制。因为把Fields明确分离出来Q我们也可以做到Ҏ(gu)限的列控制?br> Querycȝ使用CZ如下:<br> Query.begin().fields(TEST_FIELDS)<br>              .condition().eq(ID,"3")<br>    .end().resultType(IQueriable.TYPE_ROW_MAP)<br>    .findOne(dataSource).mapValue();<br> q里的调用接口的设计基本遵@与SQLcȝ同的风格Q只是面向主题域而不是直接针对SQL语言的封装?img src ="http://m.tkk7.com/canonical/aggbug/20539.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/canonical/" target="_blank">canonical</a> 2005-11-19 10:58 <a href="http://m.tkk7.com/canonical/archive/2005/11/19/20539.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]关于session的?/title><link>http://m.tkk7.com/canonical/archive/2005/11/16/20144.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Wed, 16 Nov 2005 12:07:00 GMT</pubDate><guid>http://m.tkk7.com/canonical/archive/2005/11/16/20144.html</guid><wfw:comment>http://m.tkk7.com/canonical/comments/20144.html</wfw:comment><comments>http://m.tkk7.com/canonical/archive/2005/11/16/20144.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/canonical/comments/commentRss/20144.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/canonical/services/trackbacks/20144.html</trackback:ping><description><![CDATA[有h认ؓ(f)jsplet中用session是个~点Q关于这一点,我想起一件以前听来的事情。我们都知道Linux的内核是帔R内存Q不换页的(不知道最 新的内核是否已经有所改变Q,Torvalds认ؓ(f)内核换页对系l性能有巨大媄响,是愚蠢的xQ所以Linux内核不能换页。据陈榕_(d)NT内核是可? 늚Q而微软内部有一个小l,专门~写工具Q对已经~译好的操作pȝ二机制代码进行优化,调整Q最l结果是NT内核可以换页Q但几乎不换,q才是微软可 怕的技术实力?br> 对于单的应用Qsession可以随意使用Q而对那些性能要求极高的应用,每一个系l架构师都会(x)如薄冰Q简单的依靠全局Cache不是真正的解x 案,在每一个细节上我们所需要的是更多的控制权而不是更多的限制。jsplet通过objectScope可以对sessionq行有效的用,q是它的 优点而不是缺炏V在一个有效的框架下,才能q行真正有序的控制。只有在对系l拥有更多假讄情况下,才能把控制施加在关键点上?br> <br> Z提一下,现在有些Z提到性能Q就对jsp直摇_(d)而对W三方品却热情拥抱。目前在javaC֌内普遍存在着一U对官方标准的漠视或者反感,不知道这是怎么回事?img src ="http://m.tkk7.com/canonical/aggbug/20144.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/canonical/" target="_blank">canonical</a> 2005-11-16 20:07 <a href="http://m.tkk7.com/canonical/archive/2005/11/16/20144.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]tpl:tagq行到底http://m.tkk7.com/canonical/archive/2005/11/16/20140.htmlcanonicalcanonicalWed, 16 Nov 2005 11:23:00 GMThttp://m.tkk7.com/canonical/archive/2005/11/16/20140.htmlhttp://m.tkk7.com/canonical/comments/20140.htmlhttp://m.tkk7.com/canonical/archive/2005/11/16/20140.html#Feedback0http://m.tkk7.com/canonical/comments/commentRss/20140.htmlhttp://m.tkk7.com/canonical/services/trackbacks/20140.htmltpl是witrix开发^C的动态xml标签技术,其基本特点表Cؓ(f)如下三个斚w:
1. 执行能力
 xml本n只是Ҏ(gu)据的描述Q而没有@环和判断的能力?br> 在tpl?lt;c:forEach>?lt;c:if>标签可以完成E序语言的执行功能,q定义了<c:tile>, <c:iif>{更方便的标{?/font>

2. 抽象能力
   获得抽象能力Q首要的一Ҏ(gu)使得创徏新概늚成本极低。很有人大量开发jsp tagQ原因就是开发tagq于ȝQ而且调整不方ѝ另外开发出的tag如果_度太小Q大量用的时候是Ҏ(gu)能的致命伤実?br>   tpl首先需要经q编译,而不是象jsp tag那样完全动态运行,而且tpl~译出的l果是无状态的Q因此解决了性能上的问题?br>   在tpl中导入外部模板的语法非常单,可以实现基本的分?br>    <c:include src="xxx.tpl" />
   更重要的是,tpl中定义了完善的库机制?br>使用?br>    <!-- 导入外部? 导入时指定名字空间ؓ(f)demo?br>         注意tpl中ƈ没有完整的名字空间支持,只能作ؓ(f)qName使用
    -->
    <c:lib src="demo_lib.xml" namespace="demo" />

 <!-- 对具有cache:timeout属性的节点应用cache修饰Q即该节点的q行内容被缓?-->
 <c:decorator type="cache" match="
//@[cache:timeout]" />

    <div id="blockA">
        <p>通过tpl:tag属性可以设定宿L{真实标签名。这U做法可以方便可视化设计Q?lt;/p>
        <input tpl:tag="demo:文本? value="in block A" otherValue="${varInJsp}" onclick="clickOnBtn()"/>
    </div>

    <div id="blockB">       
       <p>分页表格:</p>
        <img tpl:tag="demo:分页表格" headers="fieldA,fieldB" pager="${pager}" />
    </div>

    <div id="blockC">
      <p>bodyTag标签的调?</p>
        <demo:循环data>
            <input type="text" value="${row}" /> <br/>
        </demo:循环data>
    </div>

    <div id="blockD" cache:timeout="1000s" >
        <p>条g标签的调?</p>
        <demo:当Num_?gt;
            <p>?thisObj中的变量 'num' 的值大?的时候显C句话 </p>
        </demo:当Num_?gt;
    </div>

定义库文件demo_lib.xml
<!--
     自定义标{属性:(x)
  type: simpleTag, bodyTag 或?conditionTag, ~省为simpleTag
  importVars : 每个自定义标{օ有自q变量I间Q需要通过importVars来明指定从外部变量I间中导入的变量?br>  demandArgs: 调用时必L给些参数的?br>  otherArgs: 如果指定了该参数Q则调用自定义标{时能够使用的参数就必须在demandArgs和otherArgs指定的范围之内?br>-->
<demo>
    <!-- 一个简单的tagCZQ?直接输出变量。这里demandArgs指定调用时必L供的变量?-->
 <文本?demandArgs="value" otherArgs="otherValue,onclick" type="simpleTag" >
  <p> -----------------------------------  </p>
     <!-- 可以使用调用时提供的其他变量Q如otherValue-->
  <input size="40" type="text" value="${value} * ${otherValue}" onclick="${onclick}"/>
  <p> -----------------------------------</p>
 </文本?gt;

    <!-- 一个自动分表|要求传入headers(Listcd)指定表头Qpager(Pagercd)提供数据 -->
 <分页表格 demandArgs="headers,pager">
     <!-- 从外部导入tpl文g -->
  <c:include src="flex_table.tpl" />
 </分页表格>

 <!-- 一个bodyTagCZ: 循环处理thisObj中的变量data中的每一行?br>      importVars从调用环境中自动导入变量而不需要通过调用参数直接指定?br>      当然如果调用参数中指定的变量与importVars中指定的变量重复Q则调用参数?x)覆盖importVars.
    -->
 <循环data importVars="thisObj" type="bodyTag">
  <c:forEach var="row" items="${data}">
   <!-- tagBody用时标签的内?-->
   <cp:compile src="${tagBody}" />
  </c:forEach>
 </循环data>

 <!-- 一个条件标{CZ.
      条g标签一般不应该输出文本Q而是q回一个bool倹{仅当返回true的时候,调用时标{内容才会(x)被运行?br> -->
 <当Num_?importVars="thisObj" type="conditionTag">
  <l:gt name="num" value="3" />
 </当Num_?gt;
</demo>

? 意到bodyTag和conditionTag使得我们可以@环(容器Q逻辑和判断逻辑抽象成有意义的概念,而不再是一些执行的指o(h)。这U抽象能力的? 用非怾赖于xml的自描述Ҏ(gu),我们不需要付出太大的努力Q就可以在lib中封装出一个有意义的概忉|! 而且tag的参数可以指定,可以~省Q存在多U选择Q也对应着多种逻辑模型?br>通过<c:decorator>的用法可以看刎ͼ因ؓ(f)xml明确定义了结构,使得我们可以L的实施类似AOP的功能?/font>

3. 集成能力
   首先Qtpl完全W合xml规范Q与xml世界接轨Q可以自q使用xslt。例如,?br>   M标签中都可以指定tpl:xdecorator属? tpl在编译之前首先会(x)应用指定的xslt文gq行变换Q对变换后的l果再进行编译?br>   <anyTagName tpl:xdecorator="some_xslt.xslt">
  ...
   </anyTagName>
   其次Qtpl可以使用属性标讎ͼ即tpl标签不仅仅可以通过标签名来标识Q而且可以通过tpl:tag属性来标识。例?
   <input tpl:decorator="demo:文本? />
   ?<demo:文本?/>{效?br>   q种做法避免了tpl侵入html模型Q得我们可以利用现有工具对tplq行所见即所?WISIWIG)的设计?/font>

   再次, 在tpl中用EL(Expression Language)语言Q集成java数据模型?/font>

   W四, 在tpl中可以采用如下方式实现强cd化,完成与java的接口?br>   interface ITest{
     void test(String name, int value);
   }

   <o:class name="MyClass" implements="ITest">
    <test args="name,value" >
   ...
    </test>
   </o:class>
   q种能力可以在数据源的filter中用?/font>

   W五Q?tpl可以L的集成其它xml技术。例如,tpl集成了ant
   <ant:run>
  <echo message="xxx" />
   </ant:run>
   因此Q我们立L有了ant的数千个功能标签?/font>

canonical 2005-11-16 19:23 发表评论
]]>
[导入]jsplet与OOhttp://m.tkk7.com/canonical/archive/2005/11/15/19841.htmlcanonicalcanonicalTue, 15 Nov 2005 04:34:00 GMThttp://m.tkk7.com/canonical/archive/2005/11/15/19841.htmlhttp://m.tkk7.com/canonical/comments/19841.htmlhttp://m.tkk7.com/canonical/archive/2005/11/15/19841.html#Feedback0http://m.tkk7.com/canonical/comments/commentRss/19841.htmlhttp://m.tkk7.com/canonical/services/trackbacks/19841.htmljsplet中的对象化ƈ不是一Uy妙的trickQ而是一U设计上的必然。现在大家言 必称OOQ可OO到底意味着什么,除了书本上的话语Q你能不能用自己的话描述一下,能否体会(x)到那U必然。OO如果是一个有效的概念Q它在Y件以外的领域? 否有着对应。按照早期教U书的说?OO是ؓ(f)了模拟现实世界,q种说法只是反映了设计上的一U困境,一U思想上的贫乏。面向对象最直接的意义在于标CZ? 态与行ؓ(f)之间的耦合Q此后在E序中可以用一U显C的Q一致的方式来操U这个集合体。在界面上,我们看到一个组Ӟ在模型层Q我们看到的q是那个对象Q在? |文仉我们q能清晰的L别出它来。可在webworkq种面向action的框架中Qpackage看v来像对象Q在action层却不见了,当我们需 要同时用两个action的功能的时候(如同时列出role和user)Q以前的action不能用了Q只能再写一个。想一惻I我们最需要多概念, 最需要做多少工作Q才能在软g中徏立一个合适的概念框架Q怎样才能保持q种框架中的张力?/font>

canonical 2005-11-15 12:34 发表评论
]]>
[导入]jsplet与IoChttp://m.tkk7.com/canonical/archive/2005/11/15/19840.htmlcanonicalcanonicalTue, 15 Nov 2005 04:34:00 GMThttp://m.tkk7.com/canonical/archive/2005/11/15/19840.htmlhttp://m.tkk7.com/canonical/comments/19840.htmlhttp://m.tkk7.com/canonical/archive/2005/11/15/19840.html#Feedback0http://m.tkk7.com/canonical/comments/commentRss/19840.htmlhttp://m.tkk7.com/canonical/services/trackbacks/19840.html关于jsplet中的object生命周期的管理以?qing)用拉模式Q如果套用现在流行的设计术语Q那是涉及(qing)到所谓的IoC设计Q控制反?
IoC 的Container现在很受q捧, 但真正的IoC设计思想q没有引起大家的重视。也许大多数Z用的都是成品吧,以至于把成品的功能等价于其所依赖的设计原理。Spring{所建立? IoC更准的说法是Dependency InjectionQ只是IoC的一U体现。其基本思想是一个对象ƈ不控制所有与它相关的部分Q而是把控制权交给使用对象的h。这里重要的是控制(? 息流Q的反{?
对象生命周期的管理也是这Pq不是由一个Manager猜测用户是否使用该对象,而是qL(fng)接标明他的态度Q直接发出指令?
? 考一下桌面应用中的资源控制手D,我们打开一个窗口,与系l进行交互,此时占用资源Q关闭窗口,则该H口以及(qing)其子H口所占用的资源都释放。在jsplet 中对象控制策略类伹{当用户从某个功能区退出的时候,卛_用户讉K其它scope中对象而放弃当前objectScope的时候,开始做资源清理工作。即 用户的行为和意向直接驱动着pȝ的对象管理层。当Ӟ如果用户一直不发出调用Q那么系l只能猜用L(fng)行ؓ(f)Q用h否已断线或者正在思考?在这U情况下Q? 如果控制资源Q则需要通过AOPlthisObj 加上cMEJB的功能?/font>



canonical 2005-11-15 12:34 发表评论
]]>
[导入]关于jsplet的一些问{?/title><link>http://m.tkk7.com/canonical/archive/2005/11/15/19839.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Tue, 15 Nov 2005 04:33:00 GMT</pubDate><guid>http://m.tkk7.com/canonical/archive/2005/11/15/19839.html</guid><wfw:comment>http://m.tkk7.com/canonical/comments/19839.html</wfw:comment><comments>http://m.tkk7.com/canonical/archive/2005/11/15/19839.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/canonical/comments/commentRss/19839.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/canonical/services/trackbacks/19839.html</trackback:ping><description><![CDATA[<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"> <tbody><tr><td><span id="gynkusp" class="genmed"><b>引用:</b></span></td></tr><tr><td class="quote">如果在Action Centric的框Ӟ要避免两个访问点Q可以这么定义?<br>view.do?&templateName=a &objectName=/@Demo&objectEvent=test </td></tr></tbody> </table> <span id="xdbucvs" class="postbody"><br>q? U做法就是程序自己处理而不是框架支持了。我说过Q工作就是那么多Q只是框架做什么和E序作什么的分工而已。说jsplet是pageZ心也不太准确Q? jsplet是以对象Z心,只是指定了希望用的视图面而已。view.jsp攑֜前面只是jsp实现上的一个问题, <br><br></span> <table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"> <tbody><tr><td><span id="ogcrxdy" class="genmed"><b>引用:</b></span></td></tr><tr><td class="quote">Action Centric 实比较ȝQ必d时传入角色列??用户列表?分页信息?JSPLet对于q个问题是怎么处理的? </td></tr></tbody> </table> <span id="wpvmhrm" class="postbody"><p><br>很简单包含两个子面 <br>list_both.jsp <br><jsp:include page="role_list.jsp?objectName=/@RoleManager" /> <br><jsp:include page="user_list.jsp?objectName=/@UserManager"/> <br>? 讉K的时候通过指定eventTarget参数卛_事件\由到合适的对象Q没有响应事件的对象thisObj里的内容不变Q因为前台view昄内容? 不变。注意这里role_list.jsp和RoleManager, UserManager对象都是独立开发的?</p><p><table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><span id="zlcarqa" class="genmed"><b>引用:</b></span></td></tr><tr><td class="quote">q个时候,role_list.jsp ?user_list.jsp里面都有一?thisObj。而且q两个thisObj的scope都是 sesession ?</td></tr></tbody></table></p><span id="dntgiou" class="postbody"><p><br>? 意所有的对象模型都需要状态保持机Ӟ所以thisObj实被保持在session中。在webwork2中如果希望在多个action之间协调Q则? d某个对象保留在session中,否则是采用无状态模型,所有的状态数据都持久化在数据库中Q每ơ输出的面都和某个action产生l定Q一U行 为相养IQ则Ҏ(gu)无法实现上述例子中的分解q程Q因为在action模型中状态与行ؓ(f)无法抽象C起ƈ重用Q? 当页面显C逻辑比较复杂的情况下Q页面本w也有一些(f)时状态需要保持,MVCq不是意味着所有的状态都是需要持久化到数据库中的关键业务数据。在每个层次 上都可能需要保持状态,MVC只是说某些状态变量更加重要,可以驱动其它层次而已?<br>另外说thisObj的scope是session也是? 准确的。首先注意到jsplet通过对象化实C状态和行ؓ(f)抽象CP此后E序拥有了对这个整体的控制权,在jsplet中存在着对象的生命周期控 Ӟ对象的scope是自定义的,对象的生命周期是session的子部分Q而不是整个session生命周期范围内都存在。请注意一下这U控制策略带? 的可扩展性。我们拥有了对象生命周期的控制权Q依然可以采用无状态设计,但在需要保持状态的时候,可以做到。而在webworkq样的action模型? 是没有这U选择权的?/p><p><table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><span id="oarisnt" class="genmed"><b>引用:</b></span></td></tr><tr><td class="quote">sessionq度使用是不好的 </td></tr></tbody></table></p><span id="qvmomag" class="postbody"><p><br>thisObj只是允许使用session,是否使用session可以自行军_Q这是一U能技术,而没有object支持Q结果是无法有效的用。另外,请仔l看清楚QobjectScope是一U非常精l的资源使用控制手段?<br></p><p>? 外不要把设计理念和性能混ؓ(f)一谈。设计体现的是对概念的把握,能够辑ֈ合适的抽象Q而性能是实际实现过E中的限制。在概念能够支持的情况下Q可以采用技? 手段解决性能问题Q或者退化到较低的层ơ,q是一U选择权。而概忉|法支持的情况下,需要各U穿墙打z的Ҏ(gu)来实现?<br><br>thisObj重要的是概念Q如果需要,它可以把状态序列化到cookie或者dotNet那种参数中,q只是个实现问题?br></p><p><table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><span id="chkwrml" class="genmed"><b>引用:</b></span></td></tr><tr><td class="quote"><br>JSPLet Action 必须?JSP ? </td></tr></tbody></table></p><span id="tbdyeoq" class="postbody"><p><br>当然可以是Q何javac, JSP Action只是IEventListener接口的一个实?。在jsplet最初的版本中,action只能写在java文g中。稍后改为可以写在jsp中也可以写在java?br><br></p></span><p><table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><span id="gsusnxh" class="genmed"><b>引用:</b></span></td></tr><tr><td class="quote">WebWork的Action本n是模型对象</td></tr></tbody></table></p><span id="bcevbly" class="postbody"><p><br>q是WebWorkq地方Q它因ؓ(f)是基于action的,没有对象化,所以只有以action作ؓ(f)模型对象的蝲体,无法捕获多个action之间的状态相x?<br>完全无状态的设计正是因ؓ(f)没有合适蝲体造成的。而jsplet中thisObj可以看作是对session的局域化Q是对session的分解。jsplet中的很多概念在webworkq种面向action的框架中都能扑ֈ对应Q只是加上了很多限制q且变得模糊了?/p><p><span id="klypoup" class="gensmall"><table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><span id="rwrmsyi" class="genmed"><b>引用:</b></span></td></tr><tr><td class="quote">没有model1?jstl+javabean) 没有struts?优雅" 定位模糊. </td></tr></tbody></table><span id="iywuwrq" class="postbody"><br>jsplet 是以非常_的方式实现对象化。再说一ơ,不要把jsplet的定位向那些开源框架上靠。jsplet的开发时间大概与那些开源框架同时进行的。仔l看? 设计中的可扩展性。xwork的所有特性jsplet都可以实玎ͼ而且jsplet多提供的部分是对象化?<br></span></span></p></span><span id="zagxsci" class="postbody"></span><span id="gwzfhrb" class="gensmall"><br></span></span></span><br>? 以? q不意味着必须使用Q所有无状态设计都可以一样应用。jsplet是一U事仉动设计,在这一点上Q更像是Tapestry或者JSF。基? actioin的设计是真正的无能用sessionQ它不敢应用session的原因是它对session没有控制力。而在jsplet中对 session的用控制是很自然的Q当你需要对象的时候,当你需要这个状态的时候,它才存在。它出现是因为需要它存在。在面向action的框架中Q你 仍然需要解决状态问题。只是框架无法提供支撑,自己解决而已?<br>我想Q大概大多数人开发的E序都是CURD的堆砌,所以很隄解一个复杂的应用中的状态管理的必要性。有了对象支持之后,才构成整个框架的概念上的完备性?</span><img src ="http://m.tkk7.com/canonical/aggbug/19839.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/canonical/" target="_blank">canonical</a> 2005-11-15 12:33 <a href="http://m.tkk7.com/canonical/archive/2005/11/15/19839.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]jsplet与webwork的概念对?/title><link>http://m.tkk7.com/canonical/archive/2005/11/15/19838.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Tue, 15 Nov 2005 04:32:00 GMT</pubDate><guid>http://m.tkk7.com/canonical/archive/2005/11/15/19838.html</guid><wfw:comment>http://m.tkk7.com/canonical/comments/19838.html</wfw:comment><comments>http://m.tkk7.com/canonical/archive/2005/11/15/19838.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/canonical/comments/commentRss/19838.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/canonical/services/trackbacks/19838.html</trackback:ping><description><![CDATA[<font size="3"><font color="#000000"><span id="pbhnavy" class="postbody">jsp本n提供的是一个有限状态机模型(FSM)QW(xu)eb讉K模型直接体现了这一? action?XXXX?<br>action对应于方法名QXXX是方法的参数。在q个讉K模型中没有指出状态存储在什么地方,因ؓ(f)它假讑֐台是一个整体,构成一个巨大的状态集?<br>? q种模型注定是过分简化的Q所以会(x)有很多的发展。发展的方向是逐渐_化,识别出相关的部分Q把它们l织C赗其实可以从各个框架的开发过E来看出q? U演化的q程? Struts最早只有一个全局配置文gQ现在多了一个模块的概念。WebWork是在Struts之后设计的,提供了一个所谓的package的概念,? 一堆action和interceptorl织CP其设计中package的extends属性看上去是不是有点眼熟。概念多了就要分模块Q这一点在 面向对象之前存在了Q也W合Struts的发展历E,只是WebWork的这个extends不再是简单的模块概念了,而是一U面向对象的设计Q只? WebWork中没有实现型与名的分,每个action名对应唯一的一个actionQ所以package也可以看作是一U完全静态的对象,只有一个实 例,不是? 我们可以做一个对应,包的namespace大概可以对应于Jsplet中的objectScope, 包名大概可以对应于Jsplet中的objectType, action对应于objectEvent, 差别在于objectScope是完全动态的Qƈ参与Web对象理Q而package的namespace被创造出来之后只起了一个名字区别作用, Webwork的后l发展会(x)不会(x)在这一点上再做些文? <br>再看另外一个地斏V前台页面显C需要从模型中拿到数据,那模型对象是怎么理的, Jsp本n提供了几个管理策略application, session, request, page, 几个action需要共享状态信息怎么办?状态与行ؓ(f)的相兛_是对象化了。Webwork2没有提供对象化的手段Q不知道一般h是怎么做的Q将所有相x 作都塞在一个Action里,然后通过一个扩展参数映? q是都从session中存取模型对? session中的对象是不是越来越多,有没有h来管一? <br><br>jsplet的核心是objectManager, 它利用objectFactory来创建对象,利用objectName来管理WebObjectQ这是与|络无关? q里理的对象也不一定需要响应Web事g?<br>? 象如果需要响应事? 实现IEventListener接口Q在~省实现? Jsplet用了EventManager来管理objectEvent的响应,大致相当于xwork的工作,只是EventManager是个帮助? 象,由WebObject自己军_是否使用Q而且它是每个WebObject自己使用自己的EventManager, 而不是系l全局只有唯一的一个EventManager?<br><br>整个objectManager层面都是|络无关的,当然可以单元试? WebEngine最l实现objectManager与web环境的关联,只是它用了拉模式。特别是在视图jsp中调用WebEngine, 其最重要的作用是thisObjq个变量注入到jsp模型中。this指针其实体现了对象化的很重要的特?使用局部名而不是全局名称?<br>其实XWork本n也是可以qWeb环境应用的,特别是它可以qView来用,q是它的扩展性的一个来源?<br><br>在Webwork 中有一U叫做Model Driven的概念,使用Model Driven之后在OGNL表达中就可以直接使用model的属性和Ҏ(gu)。在jsplet使用我们自己的tpl模板引擎, 其中token解析{略是thisObj的属性和Ҏ(gu)可以直接使用Q也可以通过thisObj.xx来访问,q就如同this指针的用法?<br><br><br>再次声明Q我无意jsplet与其它框架在实际使用效果上作Ҏ(gu)Q所分析的只是Framework整体的概忉|型。数据绑定,参数和状态校验等与应用相关的功能在我们的框架中都是有着完整的解x案的Q目前不打算讨论q些?/span></font></font><img src ="http://m.tkk7.com/canonical/aggbug/19838.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/canonical/" target="_blank">canonical</a> 2005-11-15 12:32 <a href="http://m.tkk7.com/canonical/archive/2005/11/15/19838.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]jsplet:对Model 2模式的批?/title><link>http://m.tkk7.com/canonical/archive/2005/11/15/19837.html</link><dc:creator>canonical</dc:creator><author>canonical</author><pubDate>Tue, 15 Nov 2005 04:31:00 GMT</pubDate><guid>http://m.tkk7.com/canonical/archive/2005/11/15/19837.html</guid><wfw:comment>http://m.tkk7.com/canonical/comments/19837.html</wfw:comment><comments>http://m.tkk7.com/canonical/archive/2005/11/15/19837.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://m.tkk7.com/canonical/comments/commentRss/19837.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/canonical/services/trackbacks/19837.html</trackback:ping><description><![CDATA[<p><font size="3">   在Jsp Model 2模型? 用户的所有请求提交给C(j)ontroller Servlet, 由Controllerq行l一分配, q且采用推的方式不同的UI昄l用戗? q种推方式在很多人看来是一U优点,因ؓ(f)在Struts{MVC实现中具体推送的UI可以在配|文件中配置Q配|完成后q可以通过一些可视化分析工具得到 整个站点地图。在Model2模式中基本的讉K格式?<br>       <font color="#000000"><strong>action.do?其他参数</strong></font>   </font></p> <p><font size="3">? 本h从未应用qModel2模式Q但与我们的jsplet框架Ҏ(gu)Q我认ؓ(f)q种推送方式在大多数情况下q不是什么优炏V如果将一ơweb讉K看作是一ơ函 数调用,则按照Model2模式Q这个函数的q回情况是不定的,需要由一个额外的配置文g来确定。而我们知道,一个返回情况不定的函C般不是什么良 好的设计。在我们的框架设计中Q一个基本的观点是尽量将自由度暴露给实际控制它的人。实际上Q在大多数情况下Q页面编制h员知道应该用哪个页面来昄? 据,他们q不需要一个额外的配置文g。Jsplet使用如下的url格式:<br>       <strong>视图jsp?objectName=模型对象?amp;objectEvent=响应事g?amp;其他参数<br></strong>举一个具体的例子:<br>   </font><a ><font size="3">http://my.com/demo_view.jsp?objectName=/@Demo&objectEvent=test</font></a></p> <p><font size="3">demo_view.jsp是指定的昄面, 其代码如?<br>[code]<br><%@ include file = "/engine.jsp" %><br><!-- 相当于在jsp模型中增加了一个新的变量thisObjQ从而实现jsp面的对象化 --><br><c:out>${thisObj.testVar}</c:out><br>[/code]<br>objectName被WebEngine映射到session中的一个对象,在demo_view.jsp中成为thisObjq个变量Q这q当于java语言中的this指针Q从而实Cjsp面的对象化?/font></p> <p><font size="3">WebEngineq将objectEvent映射C个Action响应函数q自动调用它Q具体的Action代码写在一个独立的java文g或者jsp文g中?br>DemoAction.jsp<br>[code]<br><%@ include file = "/jsp_action_begin.jsp" %><br><%!<br>    //<br> // objectName映射为thisObj, objectEvent=test映射对actTest的调?br> // 在这里增加一个actXXX函数之后Q即可通过objectEvent=XXX来访问,不需要Q何配|?br>    public Object actTest(){<br>  // thisObj中的变量可以在视图中使用<br>  thisObj.set("testVar","hello");<br>  return success();<br> }</font></p> <p><font size="3"> // 如果存在actBeforeAction函数Q则该函数在所有action函数之前调用<br> public Object actBeforeAction(){<br>  return success();<br> }</font></p> <p><font size="3"> // 如果存在actAfterAction函数Q则该函数在所有action函数之后调用<br> public Object actAfterAction(){<br>  return success();<br> }<br>%><br><%@ include file="/jsp_action_end.jsp" %><br>[/code]</font></p> <p><font size="3">在Jsplet框架中只需要注册对象,而不需要单独注册每个action?br>register.jsp<br>[code]<br><%<br>    WebEngine.registerType("Demo", new WebActionType("/demo/action/DemoAction.jsp"),pageContext);<br>%><br>[/code]</font></p> <p><font size="3">与Jsplet 框架Ҏ(gu)QModel2是对action的徏模而不是对object的徏模,卛_相当于将objectName,objectEvent? view.jspl定在一起定义ؓ(f)一个访问点action.do,l定q程中需要一个配|文件来固化view.jsp和action之间的联pR因? Model2q没有完全分view和modelQ它隐含假定着objectName只具有一个objectEvent, q且l定了一个具体的view(出错面除外)?br>例如, 我们需要两个不同的view来显C同一个数据,则在Model2E序中可能需要配|两个独立的讉K点,而在我们的框架中只需要用两个不同的url:<br></font><a href="mailto:a_view.jsp?objectName=/@Demo&objectEvent=test"><font size="3">a_view.jsp?objectName=/@Demo&objectEvent=test</font></a><br><a href="mailto:b_view.jsp?objectName=/@Demo&objectEvent=test"><font size="3">b_view.jsp?objectName=/@Demo&objectEvent=test</font></a><br><font size="3">同样的webE序甚至可以在前台通过XMLHTTP方式来调用而不需要额外配|?</font></p> <p><font size="3">在Jsplet框架中采用的是对象化的方式而不是Action化的方式Q因此存在着多种面向对象的扩?而所有的扩展都直接体现在url格式的细化上Q一切都在阳光下?br>  在Jsplet中objectName是WebObject的名Uͼ在全pȝ内唯一Q其格式定义? </font><a href="mailto:objectScope@objectType$objectInstanceId"><font size="3">objectScope@objectType$objectInstanceId</font></a><br><font size="3">1. 对象cdobjectType<br>  我们需要注册的是对象类型而不是完整的对象名,一个对象类型可以对应于无数个完整的对象名,例如我们注册了Democd的WebObject, ?/font><a href="mailto:objectName=/@Demo"><font size="3">objectName=/@Demo</font></a><font size="3">?/font><a href="mailto:objectName=/left/@Demo"><font size="3">objectName=/left/@Demo</font></a><font size="3">对应的处理文仉是DemoAction.jsp?br>2. 对象生命周期控制objectScope<br>  objectScope为WebObject所在的域,其格式符合Unix路径命名规范。JSP模型本n支持一些预定义的对象域Q包括page, request, session, application{。但Z能够反映现实世界中的对象l织l构Q对象域必须是允许自定义的。objectScope被组l成一个树(wi)形结构,q是一? 基本的控制结构,其控制策略ؓ(f)<br>     <strong>同时存在的对象域之间必须存在U性序关系(order) <br></strong>  当系l访问某一对象Ӟ如果该对象所在的对象域不能和现有对象的域处在同一"路径"?卛_对象域之间不能徏立父子关pL)Q系l就?x)自动销毁不兼容路径 分支下的所有对象?q种_的控制策略保证了pȝ的可扩展性,因ؓ(f)模型上可以保证始l只有一部分对象被创建?br>对象转移                                                           pȝ动作  <br></font><a><font size="3">/main/@MyObject</font></a><font size="3"> ==> </font><a><font size="3">/main/left/@OtherObject</font></a><font size="3">                       ?<br></font><a><font size="3">/main/left/@OtherObject</font></a><font size="3"> ==> </font><a><font size="3">/main/@MyObject</font></a><font size="3">                       ?<br></font><a><font size="3">/main/left/@OtherObject</font></a><font size="3"> ==> </font><a><font size="3">/main/left/@MyObject</font></a><font size="3">                  ?<br></font><a><font size="3">/main/left/@OtherObject</font></a><font size="3"> ==> </font><a><font size="3">/main/right/@MyObject</font></a><font size="3">                自动销?main/left子域下的对象Q如</font><a><font size="3">/main/left/@OtherObject</font></a><br><font size="3"> <br>3. 对象实例标识 objectInstanceId<br> 如果在某一对象域中需要包含多个同一cd的对象,可以通过objectInstanceId来加以区分,q样在同一个页面上我们可以使用多个同样cd的对象?/font></p> <p><font size="3">Jsplet中另外一个扩展是通过事g路由来支持jsp子页面的对象化。例?br></font><a ><font size="3">http://my.com/demo_main.jsp?objectName=/@Main&eventTarget=/@Sub&objectEvent=test</font></a><br><font size="3">如果指定了eventTarget参数Q则objectEvent由eventTarget对应的对象来响应?br>在jsp文g内部我们可以通过include语法来引入子对象Q例?br>   <jsp:include page="</font><a href="mailto:sub_view.jsp?objectName=/@Sub"><font size="3">sub_view.jsp?objectName=/@Sub</font></a><font size="3">" /><br>Q注Q我不是非常清楚Tapestry具体是如何实现对象化的,熟?zhn)Tapestry的朋友可以介l一下)</font></p> <p><font size="3">在Jsplet中可以通过配置文g来支持对Action的interception, 例如<br>[code]<br><factory><br><listener-filter  class="global.LogFilter" /><br><post-listener class="global.CommonActions"/></font></p> <p><font size="3"><type name="Demo"><br> <!-- 如果未指定object, 则缺省ؓ(f)WebObjectcd --><br> <object class="demo.MyWebObject" /><br> <listener><br>  <filter event="query*|select*" class="demo.LogFilter" /><br>  <url-listener url="/demo/DemoAction.jsp" /><br>  <url-listener url="/demo/DemoAction2.jsp" /><br> </listener><br></type></font></p> <p><font size="3"></factory><br>[/code]<br>在上面这个配|文件中QDemoAction.jsp和DemoAction2.jsp是chain关系Q即事g响应的传播模型中Q如果event没有被标Cؓ(f)stopPropagation,׃(x)传递到下一个listener?/font></p> <p><font size="3">lg所qͼ可以看到在目前多变的需求环境下QModel 2已不是一U非常完善的WebE序模式Q一些重要的设计需求在Model 2模式的推方式中很隑־到合适的表达?/font></p> <img src ="http://m.tkk7.com/canonical/aggbug/19837.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/canonical/" target="_blank">canonical</a> 2005-11-15 12:31 <a href="http://m.tkk7.com/canonical/archive/2005/11/15/19837.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://m.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://dukane1688.com" target="_blank">߳ëƬڵ </a>| <a href="http://bjmyhfc.com" target="_blank">Ƶѹۿ</a>| <a href="http://js-jiarui.com" target="_blank">߹ۿ</a>| <a href="http://ghiearning.com" target="_blank">þAVҹƷһ </a>| <a href="http://shlamore.com" target="_blank">þþƷѹۿ</a>| <a href="http://1314a.com" target="_blank">ŷ뾫ƷVA</a>| <a href="http://www55nana.com" target="_blank">һëƬѲƵ </a>| <a href="http://864007.com" target="_blank">þþþ޾Ʒ˵</a>| <a href="http://bobostrong31.com" target="_blank">Ʒ޾Ʒ2021</a>| <a href="http://ydysmedia.com" target="_blank">ƷҹѸ</a>| <a href="http://kingleadsw.com" target="_blank">337Pձŷ޴ͼ </a>| <a href="http://zanyoo.com" target="_blank">ݺɫúݺݺۺ</a>| <a href="http://kimheezk.com" target="_blank">Ƶ߹ۿ</a>| <a href="http://shunfk.com" target="_blank">ɫ͵͵ۺAV</a>| <a href="http://zygwkqf.com" target="_blank">þþþþùaѹۿ </a>| <a href="http://hwjyrck.com" target="_blank">һƬѿ</a>| <a href="http://njbyz.com" target="_blank">þþþ޾ƷĻ</a>| <a href="http://hberay.com" target="_blank">㽶Ƶѿ</a>| <a href="http://7755ga.com" target="_blank">AVר4SE </a>| <a href="http://qu41.com" target="_blank">պשר2020</a>| <a href="http://wyj4.com" target="_blank">AVһ</a>| <a href="http://acccx.com" target="_blank">ˬָ߳BBƵѿ </a>| <a href="http://147v.com" target="_blank">91˿߹ۿ</a>| <a href="http://528676.com" target="_blank">˾Ʒ2020</a>| <a href="http://uiui6.com" target="_blank">ѾƷԲĹۿ</a>| <a href="http://2886868.com" target="_blank">һëƬڲ</a>| <a href="http://tuopumao.com" target="_blank">һӰ</a>| <a href="http://2828228.com" target="_blank">Ұ߹ۿ3</a>| <a href="http://ddtase.com" target="_blank">Ʒ޹av</a>| <a href="http://www73234.com" target="_blank">ҹ޾Ʒҹ³˿Ƭ</a>| <a href="http://imfever.com" target="_blank">Ʒѹۿ</a>| <a href="http://zhuanjiao521.com" target="_blank">պƵ</a>| <a href="http://https357171.com" target="_blank">ƷƵ</a>| <a href="http://520xiang.com" target="_blank">һѲƵƬ</a>| <a href="http://maomi02.com" target="_blank">þþþAV</a>| <a href="http://33338x.com" target="_blank">Ʒþþþù</a>| <a href="http://jhc2go.com" target="_blank">ŷһ</a>| <a href="http://8888kkk.com" target="_blank">þþƷƷëƬ</a>| <a href="http://276194.com" target="_blank">ձ˳ɻҳ߹ۿƵ</a>| <a href="http://whdy888.com" target="_blank">ƷƬѿ</a>| <a href="http://www-070755.com" target="_blank">avӰ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>