posts - 176, comments - 240, trackbacks - 0, articles - 7

http://www.bstek.com/
    上海锐道的Dorado框架号称是一个基于构件技术的、面向B/S和多层架构体系的web应用开发平台, 其前身称为Extra。从具体功能来看,如果将其看作是一个全功能的web应用开发平台, 那它现在的功能集显得就太单薄了一些, 其主要部分还是提供了一些前台的界面控件, 其他如web框架部分,很像是struts的一个简化版,没有什么特异之处。
    Dorado的技术特点是大量采用ajax技术来实现前台控件. 其前后台交互采用了自定义的基于xml格式的rpc方式, 而数据绑定使用了xml数据岛,例如
    <xml id="__datasetEmployee" >
    <records>
    <record isCurrent="true"  state="none" >
    <new>,~73~73~73~73~73,~68~68,~44~31~32,true,true,295113600000,2034.0,,</new>
    </record>
    </xml>
    record内部使用的是Dorado私有的编码/解码规则, 大概是为了压缩数据量吧.
    从Dorado目前提供的界面来看还是比较丰富的,基本满足了一般信息系统开发的需求, 但是其可扩展性似乎并不是很好. 它虽然号称是组件式开发,但是其前台和后台引擎似乎都没有提供完善的组件模型支持, 只是实现了一些既定的界面组件而已.
    1. 其前台的js函数中存在着大量针对数据类型的switch语句,似乎其所能够支持的控件类型已经内置在前台引擎中, 如果我们要增加一种新的界面组件大概需要在各处修改引擎代码, 缺乏一种抽象机制.
    2. 后台ViewModel模型似乎是想构造出一个Component架构来, 但这个模型目前看起来明显没有Echo2这样的组件模型精致, 似乎缺乏一种一致的组件重组机制.  Dorado的ViewModel是有状态的, 通过RPC机制, 它实际上可以独立于系统web层与前台控件交互.
    3. Dataset是Dorado中最重要的数据供体接口, 从它所提供的方法 getField,deleteRecord, insertRecord, movePrev, moveNext, getPageSize等可以看出, 这明显是绑定到了可分页表格的数据模型上. 实际上整个系统设计似乎都隐含假定了一个Table模型, 例如Validator接口中具有一个函数 ViewField getField(), 这里明确假定了validate只能针对单个字段进行, 而不是属于某个整体组件的.
    4. Dorado中所有组件的界面代码生成都是以程序方式进行的, 没有模板机制. 因而增加新的控件的实现时, 需要在后台通过java代码输出一部分界面, 在前台通过js脚本动态更新界面, 工作量相当大.
    5. Dorado中界面输出应该是通过Outputter接口来进行
      public interface Outputter{
        public String getStartOutput(HttpServletRequest req, Object o)throws Exception;
        public String getEndOutput(HttpServletRequest req, Object o) throws Exception;
      }
      这里一方面与web层形成了绑定,另一方面它必须在内部完整的生成界面代码之后一次性传入response, 这无疑加重了后台的内存压力. 输出分成了StartOutput和EndOutput大概是为了支持布局组件等容器类组件, 相当于是组件内部可以有一个洞, 这与Jsp Tag模型是匹配的, 但是这种方式很难以高效率实现界面上的结构融合.
    7. Dorado似乎没有直接提供组件的再封装机制, 在现有组件中作局部修正往往需要通过代码方式来进行.例如表格中的性别字段需要显示图片而不是文字, 则需要在Column的onRefresh事件中写入下代码,
            if (record.getValue("sex")){
        cell.innerHTML = "<img src='images/man.gif'>";
        }
        else{
        cell.innerHTML = "<img src='images/woman.gif'>";
        }
    这明显已经不是可配置的内容了. 如果我所需要增加的代码是一个复杂的组件, 这里就很难进行处理了.
    6. Dorado的技术绑定在了IE浏览器上, 无法兼容其它浏览器, 这有些偏离目前的标准化方向.

    目前的快速开发平台的一个共同特点是集中在单表的CRUD(Create Read Update Delete)上, 可以快速完成单表或主从表的增删改查. 这本也是正确方向,毕竟目前系统开发中的大量工作都是重复性的简单劳动, 但是一般系统设计中为了支持单表操作而在建模的时候引入了对表格模型过强的依赖,  大大降低了系统的可扩展性. 另外现在一般web组件框架的设计往往是模仿桌面开发领域的组件模式, 希望提供完全黑箱式的组件调用方式, 这其实是放弃了web开发的优势.  实际上借助于xml格式的规范性和简单性, 我们完全可以提供更加强大的结构组件, 并把组件封装的能力开放给普通程序员.

posted @ 2006-04-02 14:57 canonical 阅读(2161) | 评论 (2)编辑 收藏

    http://www.ezone.com.cn
    同方这个公司在我的印象中更像是个系统集成商,在软件方面没有什么独特之处。不知道是否是待遇问题,我也未听说同方旗下招揽过什么软件高手。同方最近两年 在软件平台方面花了一些气力,据说有70多个人,干了一两年,将同方以前的项目进行提炼,开发了ezOne平台。现在同方各个事业部开发新项目的时候好像 要求使用该平台,不过可能是涉及到总部和各个部门分钱的问题,下面的人未必有很大的应用积极性。
    同方的特点是做过大量项目,行业经验多,所以ezOne中提供了很多行业组件。ezOne的一个核心部分是portal服务器,是基于Apache项目组 的Jetspeed修改而来,应该是符合JSR168标准的,所强调的概念也正是应用集成。以前扫过一眼ezOne的代码,感觉质量一般,性能可能会有一 些问题,但编码还算工整。同方握有大量国家资源,应该不至于成为平台产品开发商,开发平台的目的大概还是降低自身开发的难度。其产品倾向于符合标准,中规 中矩,大概很难有什么创新之处。ezOne中很多基础组件都是独立开发的,例如存储层,没有使用hibernate等开源软件。

posted @ 2006-04-02 14:53 canonical 阅读(1429) | 评论 (5)编辑 收藏

   http://www.kenoah.com
   前两天和科诺的研发经理聊了一会,也简单看了一下他们的演示。因为比较匆忙,没有谈到什么实质性的内容,只是有一个粗浅的印象。科诺目前的发展重点还是国 外的外包业务,其网站上相关介绍材料很少,不过据说今年将投入较大的资源在国内公司建设和市场开拓上。
    科诺产品的特点是代码生成。经过可视化配置之后,可以根据模板生成jsp源代码,程序员可以基于这些代码进行修改。据说遵守一定的规则之后,自动生成的代 码与手写代码是相互隔离的,自动生成的代码可以无限多次生成而不影响手写代码质量,但我未看到演示。科诺生成的页面只支持IE, 不支持Firefox等浏览器。大概是因为其从事的主要是国外外包业务,其界面的美观程度一般。虽然可以修改页面模板来改变界面风格,但从我实际看到的模 板代码而言,重新写一套并不太容易。
    科诺产品的功能大概是可以完成单表或者主从表的增删改查,并配合一个或者多个业务流程。其工作流引擎据说是符合WFMC规范的,但从实际操作上看,似乎不 是一个通用的工作流引擎。至少给我演示的时候,工作流步骤的每一步,actor所能采取的操作是固定的,如退回,通过等,似乎是为审批定制的。
    与普元EOS相比,科诺在功能上还是要弱不少。在开发工具上,也显得要简单许多。与普元EOS类似的是,科诺的产品似乎也只是利用工具根据现成的模板制造 固定模式的代码,在设计思想方面并没有什么本质性的突破,与其宣传的组件思想相差甚远。如果要超越自动生成的代码作一些事情,这些平台都无法提供什么有力 的支持。科诺所谓的业务组件似乎就是对table的描述,其设计工具不算太好,至少我没有找到一个汇总视图让我可以看到所有已经配置的字段属性。在设置复 杂字段或者汇总字段方面,科诺的产品也有很多限制,不太灵活。在前台框架方面,科诺写了一个类似于struts的框架,其他就乏善可承了。流程方面的设置 被称为所谓的流程组件,运行时可以通过一个js库在界面上进行展现。不同的业务组件应该可以对应到同一流程组件,这大概就是科诺所谓的组件重用了吧。开发 工程文件以xml格式进行存储,看了一眼,相当复杂,竟然还和SOAP有关系,不知道他们为什么这么设计(符合标准?)。
    在科诺的另外一个印象是,公司里有不少女性程序员在干活。看来至少他们的产品可以由初级程序员掌握并满足美国外包开发的需求。

posted @ 2006-04-02 14:50 canonical 阅读(1845) | 评论 (7)编辑 收藏

   前两天一位普元的朋友衣风http://blog.sina.com.cn/u/1495516693在我的blog上留言,谈到对数据总线的不同看法. 我本人并未使用过普元EOS,所做的判断只是基于我个人肤浅的第一印象, 很有可能是不准确的. 不过, 目前我仍然坚持自己对于普元EOS的看法,呵呵.
    
    1. EOS产生的xml描述文件中的大量条目都是EOS自身的结构要求,而与实际业务无关,即EOS描述文件中的有效信息量密度很低.
    衣风认为条目并不是EOS自身的结构要求,而是业务对象的结构描述. 这里我的看法是业务对象应该尽量通过领域(Domain)语言来描述, 领域信息的外在表象应该尽量是卷缩的,而不是展开的, 应该尽量是抽象的而不是实现细节层面上的.例如:
    <function class="test.MyFunctionProvider">
        <args>
            <arg>
                <name>argA</name>
                <value>3</value>
            </arg>
        </args>
    </function>
    以上信息可以描述一个方法调用, 这里的function, args, arg, name, value等标签的设置都是解析器为了理解该调用的语义而规定的结构元素,这些元素并不属于函数本身. 例如我们可以规定如下的调用格式来简化描述文件而不损失信息,
    <function class="test.MyFunctionProvider">
        <arg name="argA">3</arg>
    </function>
    而在我们的工作流引擎中, 业务操作的调用以封装后的形式出现
    <BusinessA:DoWorkA argA="3"/>
    通过标签封装之后, 我们在调用的时候所需要提供的信息是最小化的, 每一个涉及到的元素都是有着业务含义的, 而将解析器本身的结构要求隐蔽在封装的标签定义中.此后我们如果更换了实现,而业务需求不变, 则我们的调用处是不会受到影响的.
    现在基于xml语法的文件格式很多, 我们的工作流引擎也采用了xml描述. 但是我们的一个基本观点是, xml配置文件解析器不应该直接理解文件中所有的标签, 即它只需要理解自身的结构元素, 而为引入Domain知识保留余地.
   
    2. 普元EOS中的结构似乎很难进行有效的扩展。而所谓的xml总线技术更加剧了这一点
    衣风认为"正是将XML作为数据传递的总线,才使应用在数据层次上具有了较强的扩展能力"。从面向对象的观点看, 程序中普适性的基本基元是数据与行为的集合体, 而程序模块之间的交互也绝不仅仅是通过数据来进行, 而是往往呈现出一种数据与行为的交织状况. 普元的模型应该包含了大量发生紧密关联的局部元素, 它们应该处在同一进程(状态)空间中, 直接访问对象应该是最简单,最经济, 最完备的信息传递方式, 而"xml节点的表达能力远远超越了普通的数据类型,但充其量也不过是对现有数据的规整的树形表示,并不具有动态计算能力(甚至是最简单的lazy evaluation)". 实际上对于所谓的总线, 最简单的模型是一个可以动态管理的变量集合, 那么一个Map就足够了. 在集合中我们可以保存各种对象, 比如xml节点, 但是又不限于xml节点. 从建模的角度上说, 把xml节点定义为一级集合元素我认为是不合适的. 通过对象的成员函数, 我们在对象图中可以包含大量的动态计算信息, 例如
     obj.getSomeCalculatedAttribute().getLazyLoadValue()
    这些动态语义在纯数据含义的xml总线技术中不知道如何表达.
    对象图表达数据关联的能力也强于树形结构的xml节点, 例如 obj.getRefObj().getRefObj() == obj, 不知道这样的关联在普元EOS的数据总线中如何表达.
    在并发访问中如果需要同步, 对于对象, 我们可以使用synchronized机制, 但是对于xml节点不知道如何才能有通用的处理方式. 

posted @ 2006-04-02 14:47 canonical 阅读(1873) | 评论 (2)编辑 收藏

     http://www.primeton.com/

    普 元软件公司是国内专业的中间件提供商,从国家得到了不少投资,做出来的东西也是相当的庞大。最近普元EOS的宣传和发展的势头都很盛。其宣传材料中屡次提 到“软件的涅磐“这一用语,这明显是一种危言耸听之举,当然这在业内也不算什么新鲜的事情。按照EOS的宣传,"以图形化的构件组装方式“画”出来的软件 无论从结构上、形式上还是开发过程上都堪称简捷而美的软件"。这一提法倒是别开生面。图形化与简洁,与美竟然还存在着这样必然的联系,实在是一种创举。
     从普元公开的资料来看,EOS的一个鲜明特征是全面基于xml描述,即所谓的xml数据总线。表面上看起来,xml结构内置于系统内核中似乎很时尚,但实 际上,EOS产生的xml描述文件中的大量条目都是EOS自身的结构要求,而与实际业务无关,即EOS描述文件中的有效信息量密度很低。这是一个危险的信 号。EOS的xml描述本身可以看作是一种完全新的编程语言,但这个语言似乎没有什么抽象能力和组合能力,对于关联的表达能力也很弱(到处都是数字 id)。如果直接手工编写,那是一件要死人的事情。只有通过集成开发环境的可视化界面,EOS才呈现出可理解的一面。
     EOS的概念与Language Workbench是不同的,其中的结构似乎很难进行有效的扩展。而所谓的xml总线技术更加剧了这一点。xml数据总线其实与面向过程编程类似,只是过 程变成了service,数据变成了xml节点而已。对象与简单数据结构在结构表达上的本质差异就在于对象通过成员函数可以封装动态结构。虽然xml节点 的表达能力远远超越了普通的数据类型,但充其量也不过是对现有数据的规整的树形表示,并不具有动态计算能力(甚至是最简单的lazy evaluation)。丧失了动态计算能力,就意味着我们很难在系统中动态引入结构,程序中所操纵的结构都需要事前定义出来,这将极大的限制系统的可扩 展性。另一方面,xml节点受限于自身格式,其描述关联的能力也要弱于java对象结构本身。对象通过引用访问相关对象,其隐含意义是对象处于同一地址 (状态)空间中,可以非常自然的保证对象的唯一性并实现同步访问。在跨越状态空间的边界时,xml表示是有意义的,因为我们需要把所有的结构都暴露出来并 加以描述(外在化)。而在状态空间内部,我们需要更加紧致有效的表述方式。
     在具体的实现中, EOS暴露给程序员的xml操纵API相当的原始,使用起来很繁琐。在前台展示页面中,如果不使用EOS的界面组件,提取数据本身就是一种不小的困难。 EOS的前台展示组件与后台的结合也比较弱,后台改变之后,缺乏有效的手段来检测并保证前后台结构的同步性。所谓的前台构件层似乎只是提供了一些帮助函数 和功能固化的组件,并没有提供什么有效的利于结构抽象和结构重组的机制。
     整个EOS的构架看起来很象是一个monster, 我很难想象它的各个部分如何才能独立的,深入的发展下去。

posted @ 2006-04-02 14:45 canonical 阅读(1598) | 评论 (0)编辑 收藏

  在采用AJAX技术的应用中, 常见的是两种架构设计, 一种是采用RPC(Remote Procedure Call)方案, 后台应用直接将java对象包装为service接口, 在js对外暴露(java对象完全不知道web层), 在js中通过类似函数调用的方式访问后台服务.而另外一种方案是在后台维持一个前台DOM节点的映象,触发前台事件之后, 前台引擎自动截获该事件, 并翻译为对后台事件监听器的调用, 将请求提交到后台, 后台程序处理请求之后更新后台DOM节点, 然后将页面变更部分传回前台页面. 这两种方案一种是倾向于在js中提供自我封闭的程序模型(对远程服务的调用体现为对一个js函数的调用), 一种是倾向于在后台提供封闭的程序模型(对前台页面的更新体现为对一个后台java对象的属性和结构的改变). 这两种方案的共同之处在于它们都试图在一定程度上屏蔽前后台程序的交互细节, 而提供一种统一的程序模型.
  但是我们需要记住软件设计的第一要义在于系统的分解, 而Browser和Server之间客观存在的http信道是天然存在的一种分界线. 任何强迫我们忘记B/S之间的界限的技术都是需要谨慎对待的. 例如控制后台对象的权限问题, 很多RPC方案限制了应用程序对于web接入层的直接接触, 而只能通过AOP(Aspect Oriented Programming)技术来动态织入权限控制代码. 在实际使用中, 这种方式往往因为service接口函数的多样化而造成配置上的繁琐.  而在我们的体系架构中, 系统边界划分在web访问层上(而不是java service层), 借助于web访问协议自身的一致性和透明性, 我们只需要如下实现
   Object invokeWebEvent(){       
     return new ActionMethodInvocation(getWebObject(), getObjectEvent(), getInterceptors()).proceed();
   }
就为所有WebObject加入interceptor堆栈, 完全不需要AOP的动态织入技术.
  在witrix平台的设计中, 因为大量采用pull方案, 我们对于前后台交互方式采取的是完全开放的态度, 前后台的交互接口完全定义在web访问层上(即前台程序直接访问一个url获取数据), 尽量避免将系统架构的限制引入到应用程序设计中来. 确实, Browser和Server之间的原始交互方式是受限制的, 狭窄的, 但是从系统设计的角度上说, 这正是异构系统集成和进行系统核心控制的最好场所, 任何试图独占该连接信道并在层层封装之后提供更加丰富的访问语义的努力在我看来都是可疑的.
 

posted @ 2006-04-02 14:43 canonical 阅读(1252) | 评论 (0)编辑 收藏

1. 对象的一个特性是局域化。每一个对象函数(非静态函数)都是在对象的上下文中调用的,因而隐含假设了一定的环境信息,这些信息以封装的形式被使用。
   一个具体的体现是函数的命名,如果没有对象,我们必须给函数进行全局命名,例如 find_friends, find_users, find_departments, 而在对象的环境下,我们可以抽象出一个采用局域化命名的接口 IQueriable.find(),实现系统的深度分解。
   在对象成员函数的内部,我们通过统一预定的名字(this指针)来访问对象环境中的变量。而在 jsplet web框架中的action和前台jsp中,我们通过thisObj变量来访问后台逻辑对象的上下文,而不需要知道对象的具体名称 (objectName)。

2. 对象的另一个特性是静态化。我们从面向过程走向面向对象时,我们思维中的图像出现了一个重大的变化:在面向过程的程序中,我们想象中存在的是一个个动态的处理过程,它们在时间轴上按照一定的顺序依次执行。而在面向对象的图景中,我们考虑的主要是一个静态化的世界,系统分解为对象,而对象是同时存在于我们的思维中的。这里一个重要的技术手段就是成员函数。例如我们编写一个成员函数getChildren(), 这个函数的语义是返回一个数据变量,概念上它是静态的,但其内部实现其实可能是很复杂的,非常的动态化:可能需要查询数据库,可能需要校验权限等等。
理想的情况下,我们可以利用成员函数封装可以实现对象图的遍历。例如  x.getParent().getChilldren(), 在微软的COM模型或者Sun的JavaBean标准下,我们可以写成
x.parent.children。
特别注意这里的属性语法原则上是与时间无关的,即在同一个时刻我们认为这些属性同时存在着,是一个静态的关系。而以下的调用出现了明确的步骤,因而明确引入了时间因素
ITree parent = node.getParent();
if(parent == null)
   return null;
List children = node.getChildren();
return children;

在witrix平台的tpl模板引擎中使用的EL(Expressin Language)表达式语法会自动处理函数返回值为null的情况,因而维护了对象图的语义,不需要中断调用过程来进行异常处理,是简化界面编程的一个重要方面。

这里顺便提一句:人的思维是倾向于静态化的,但现实世界却是在不断的变动中的。正所谓不变的只有变化。Von Neumann体系结构强迫我们在最细节处引入变化过程,很多时候是过分的负担。我们需要的是识别出各种可以静态描述的部分,集中精力于那些真正需要随需应变的应用。

posted @ 2006-03-25 11:36 canonical 阅读(936) | 评论 (0)编辑 收藏

    关于DSL(Domain Specific Language)的确切含义纷争很多,但是其核心观念还是很明确的。DSL的关键是使用领域特定的概念,即它的概念系统中具有一些非General Purpose的基元。但是这种所谓非General Purpose仅是就诠释层面而言,它所指的并不是DSL对应的形式系统。例如,在物理学中声波(sonic wave)无疑是对原子系统的集团运动模式的一种抽象,基于wave概念的声波方程可以看作是对应于原子系统的一个特定领域的DSL。从声波系统是无法逆推出原子系统的所有行为的,但是理论上量子力学在形式上同样可以采用wave描述,而它却可以构成对原子系统的诠释。
   
    DSL因为基于Domain概念,可以提高理解性是应该的,但是现实中的大多数DSL仍然存在大量技术性的形式要求,它们是很难让非计算机领域的业务人员掌握的。期待业务专家使用DSL在目前多半只是一种不切实际的幻想。但是如果认为DSL就是更甜的代码也并不适当。搜索google的时候我们使用的查询字符串也是一种domain specific language, 很多人都会使用""和-等语法结构。

    DSL应该关注用的层面(what), 而不是how-to,how-to是DSL的实现问题。从what到how to是我们希望通过DSL解析器屏蔽起来的内容,而不是DSL本身需要表达的内容。

posted @ 2006-03-25 11:24 canonical 阅读(846) | 评论 (1)编辑 收藏

    目前的框架设计中,引入元数据(metadata)已经是必然的事情,jdk5.0的annotation机制也为metadata的物理驻留位置提供了新的选择。常见的一些元数据设计方案中往往是元数据直接驱动系统的展现甚至运行过程(例如普元EOS),大有完全取代程序代码的趋势,这无疑是对元数据概念的一种滥用。一般在界面层所使用的元数据其实类似于某种新的界面描述语言,即某种特定目的的DSL(domain specific language). 但这种描述一般是不完备的, 一旦遇到扩展情况, 往往需要很多额外的工作。
    实际上并不是所有信息都要在独立的xml 中描述, 前台模板页面本身就可以是一种元数据, 前台元素之间的关联已经隐含表达了多种关系, 不需要把这些关联再在额外的xml文件中重复.  比如说一个数据集展现在页面上的时候需要支持几种操作,即对应的需要显示几个按钮. 在witrix平台的tpl模板中, 我们的调用方式大概如下
        <ui:EditTable pager="${pager}" dsMeta="${dsMeta}">
        <buttons>
          <ui:RemoveRowButton/>
          <ui:EditRowButton/>
        </buttons>
        </ui:EdiTable>
    操作集合这一信息仅在模板中表达一次.  实际上很多时候, 不同的界面我们需要展示不同的操作集合, 它本身并不一定是数据集内在的性质. 数据集的属性只能是支持全部操作的集合, 它并不需要直接对应到界面上. 对于多个界面我们需要尽量共用一个meta配置.

    在witrix平台的元数据方案中,关键是采用pull mode, 由前台模板系统驱动, 模板决定使用何种资源(包括元数据),而不是由元数据驱动整个系统的展现。当一个元数据条目不适用的时候我们可以忽略它,但是仍然可以使用元数据配置中的其他部分。这与我们的jsplet web框架的设计是一脉相承的。

    元数据的驻留形式本身也是很有意思的问题。假设现在我们需要描述如下信息:本字段采用input框显示,它有一个参数value. 它的meta形式可以如下,
       <inputor type="TextInput">
          <arg name="value" />
       </inputor>
    我们也可以选择如下形式
       <inputor>
        <input type="text" value="${value}" />
       </inputor>
    第二种方式的特殊之处是它选择了与html规范本身兼容的表达形式,即寄生于html格式之中。这种设计的好处在于我们只需要一个通用的模板引擎,而不需要任何特定于该控件的解析器,就可以产生最终所需的文本输出。这种元数据表达方式更重要的地方在于它是导向更高复杂性层次的自然途径。例如我们现在需要一种更加复杂的自定义控件来显示该字段,则
       <inputor>
        <ui:DateInputor value="${value}" />
       </inputor>

    在元数据的设计中,适可而止永远都是我们需要铭记在心的核心原则。对元数据描述的范围要适可而止,不要试图包罗万象。例如,在界面元数据的设计中不要对于数据供体有任何假定。一个前台表格,无论它的数据是数据库中的一组记录, 还是通过pop3协议收取的一组信件,应该都不影响它对于meta的使用。元数据引擎所能够直接理解的粒度也要适可而止。在witirx平台的元数据方案中,viewer和inputor等配置段其实是由tpl模板引擎负责解析的,在DataSourceMeta的解析器并不能识别其中的细节,它也不需要识别其中的细节。

posted @ 2006-03-25 11:19 canonical 阅读(1475) | 评论 (2)编辑 收藏

     adun今天问我xslt到底有什么用。相对于其他技术,它有什么存在的必要性。
    xslt的主要作用是对xml结构的转换,即它是一种描述结构变换规则的语言。不过也可以将它与我们更熟悉的用于生成html(结构)的模板语言作一个对比。
1. 两者都能直接生成xml格式的文本(结构)
2. 两者都有循环和判断等逻辑处理语句。
3. 模板语言可以通过EL表达式等语言取得源数据, xslt通过xpath语法取得源数据.
4. 模板语言通过自定义tag等机制实现分解和组合, xslt通过xsl:call-template等语法实现分解与组合.

     tpl等模板语言直接操纵java中的对象, 体现的是图(Graph)模型, 并通过对象函数封装了部分动态性. 一般访问的时候是通过短程关系逐级访问,例如x.y.funcA().b。利用apache项目组的jxpath包,我们也可以使用类似于xpath的语 法在对象图上进行全局访问。
    xslt使用严格定义的xpath语法访问Tree结构,具有很强的数据操纵能力,例如我们可以通过//mynode等语法轻易的实现节点的聚合,构造出 新的结构。在一般xslt包的实现中,都提供了javascript扩展,可以使用javascript构造出的数据节点。

     在tpl这样的模板语言中java中的数据对象结构与tpl中的模板结构(处理规则的结构)是两分的,而在xslt中输入数据结构与xslt自身处理规则 的机构却是统一的。实际上tpl这样的模板语言主要是基于过程语义,即先做。。。,用到。。。,然后。。。, 而xslt对于输入数据的结构具有明确的全局性假设,主要是一种转换语义,即不论在什么情况下,只要遇到。。。,就做。。。。 在xslt中可以通过xpath语法指定处理规则针对数据(输入结构)的的触发条件, 而在tpl中只能通过<c:decorator>为tpl标签指定转换器,而无法针对数据指定处理规则。

     在数据访问模型这一方面,原则上说xslt与模板语言各有优势。实际在用于html生成的过程中,xpath的全局访问和匹配能力一般难以得到发挥,而 xml格式的限制又在一定程度上阻碍了使用灵活的数据供体,这方面模板语言有一定的优势。但是xslt的约束更强也有本质性的好处,它使用xml数据并输 出xml数据,维护了结构的同质性,便于管道操作。因为假设更明确,xslt对于xml格式的数据的操纵和封装能力也要强于模板语言。例如它可以使用来为 节点追加属性。

     xslt在用于xhtml生成时的一个主要劣势在于它是对变换规则的分解之后的描述,而我们所希望得到的是最终的结果,即这些规则综合应用所生成的结果。 虽然xslt的语法是xml语言,与xhtml在语法格式上保持了一致性。但是在xslt中,xslt的标签破坏了xhtml语义上的结构,使得目前无法 做到所见即所得。我们不得不在头脑中运行xslt规则来想象最终的结果,这无疑是痛苦的。模板语言在这方面要轻松许多。

     xslt的另一个问题是有时xml语法显得过于冗长了。在操纵一些局部结构的时候,xml节点并不一定是合适的表达。例如

<xsl:value-of select="$x"/> 对比 ${x},


<xsl:call-template name="subrule">
    <xsl:with-param name="argA"><xsl:value-of select="substring-after($path,'.')"/></xsl:with-param>
</xsl:call-template>
对比
<my:subrule argA="${path.substringAfter('.')}" />

在调用子模板方面,显然xslt封装的抽象层次也要弱于tpl模板语言。


     xslt作为一种xml格式的结构变换语言,维护了xml世界的概念完整性,其意义无疑是重大的。但并不是所有时候xml都是最适的描述模型。我们最好还 是将它与其他技术结合使用。目前在witrx平台中,我们对于xslt的使用主要是对tpl模板进行布局和过滤处理,即xslt用于对处理规则进行变换, 而将根据数据生成html这个最细致的工作留给过程处理能力和封装能力更强的tpl模板语言。

posted @ 2006-03-05 00:02 canonical 阅读(847) | 评论 (0)编辑 收藏

仅列出标题
共18页: First 上一页 5 6 7 8 9 10 11 12 13 下一页 Last