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

引用:
如果在Action Centric的框架,要避免两个访问点,可以这么定义。
view.do?&templateName=a &objectName=/@Demo&objectEvent=test

这 种做法就是程序自己处理而不是框架支持了。我说过,工作就是那么多,只是框架做什么和程序作什么的分工而已。说jsplet是page为中心也不太准确, jsplet是以对象为中心,只是指定了希望使用的视图页面而已。view.jsp放在前面只是jsp实现上的一个问题,

引用:
Action Centric 确实比较麻烦,必须同时传入角色列表 和 用户列表的 分页信息。 JSPLet对于这个问题是怎么处理的?


很简单包含两个子页面
list_both.jsp
<jsp:include page="role_list.jsp?objectName=/@RoleManager" />
<jsp:include page="user_list.jsp?objectName=/@UserManager"/>
在 访问的时候通过指定eventTarget参数即可将事件路由到合适的对象,没有响应事件的对象thisObj里的内容不变,因为前台view显示内容也 不变。注意这里role_list.jsp和RoleManager, UserManager对象都是独立开发的。

引用:
这个时候,role_list.jsp 和 user_list.jsp里面都有一个 thisObj。而且这两个thisObj的scope都是 sesession ?


注 意所有的对象模型都需要状态保持机制,所以thisObj确实被保持在session中。在webwork2中如果希望在多个action之间协调,则必 须将某个对象保留在session中,否则就是采用无状态模型,所有的状态数据都持久化在数据库中,每次输出的页面都和某个action产生绑定(一种行 为相关),则根本无法实现上述例子中的分解过程,因为在action模型中状态与行为无法抽象到一起并重用! 当页面显示逻辑比较复杂的情况下,页面本身也有一些临时状态需要保持,MVC并不是意味着所有的状态都是需要持久化到数据库中的关键业务数据。在每个层次 上都可能需要保持状态,MVC只是说某些状态变量更加重要,可以驱动其它层次而已。
另外说thisObj的scope是session也是不 准确的。首先注意到jsplet通过对象化实现了将状态和行为抽象到一起,此后程序就拥有了对这个整体的控制权,在jsplet中存在着对象的生命周期控 制,对象的scope是自定义的,对象的生命周期是session的子部分,而不是整个session生命周期范围内都存在。请注意一下这种控制策略带来 的可扩展性。我们拥有了对象生命周期的控制权,依然可以采用无状态设计,但在需要保持状态的时候,可以做到。而在webwork这样的action模型中 是没有这种选择权的。

引用:
session过度使用是不好的


thisObj只是允许使用session,是否使用session可以自行决定,这是一种使能技术,而没有object支持,结果是无法有效的使用。另外,请仔细看清楚,objectScope是一种非常精细的资源使用控制手段。

另 外不要把设计理念和性能混为一谈。设计体现的是对概念的把握,能够达到合适的抽象,而性能是实际实现过程中的限制。在概念能够支持的情况下,可以采用技术 手段解决性能问题,或者退化到较低的层次,这是一种选择权。而概念无法支持的情况下,就需要各种穿墙打洞的方法来实现。

thisObj重要的是概念,如果需要,它可以把状态序列化到cookie或者dotNet那种参数中,这只是个实现问题。

引用:

JSPLet Action 必须是 JSP ?


当然可以是任何java类, JSP Action只是IEventListener接口的一个实现 。在jsplet最初的版本中,action只能写在java文件中。稍后改为可以写在jsp中也可以写在java中

引用:
WebWork的Action本身就是模型对象


这是WebWork弱的地方,它因为是基于action的,没有对象化,所以只有以action作为模型对象的载体,无法捕获多个action之间的状态相关性。
完全无状态的设计正是因为没有合适载体造成的。而jsplet中thisObj可以看作是对session的局域化,是对session的分解。jsplet中的很多概念在webwork这种面向action的框架中都能找到对应,只是加上了很多限制并且变得模糊了。

引用:
没有model1简易(jstl+javabean) 没有struts的"优雅" 定位模糊.

jsplet 是以非常精炼的方式实现对象化。再说一次,不要把jsplet的定位向那些开源框架上靠。jsplet的开发时间大概与那些开源框架同时进行的。仔细看看 设计中的可扩展性。xwork的所有特性jsplet都可以实现,而且jsplet多提供的部分就是对象化。



可 以使用 并不意味着必须使用,所有无状态设计都可以一样应用。jsplet是一种事件驱动设计,在这一点上,更像是Tapestry或者JSF。基于 actioin的设计是真正的无能使用session,它不敢应用session的原因是它对session没有控制力。而在jsplet中对 session的使用控制是很自然的:当你需要对象的时候,当你需要这个状态的时候,它才存在。它出现是因为需要它存在。在面向action的框架中,你 仍然需要解决状态问题。只是框架无法提供支撑,自己解决而已。
我想,大概大多数人开发的程序都是CURD的堆砌,所以很难理解一个复杂的应用中的状态管理的必要性。有了对象支持之后,才构成整个框架的概念上的完备性。

posted @ 2005-11-15 12:33 canonical 阅读(225) | 评论 (0)编辑 收藏

jsp本身提供的是一个有限状态机模型(FSM),Web访问模型直接体现了这一点: action?XXXX。
action对应于方法名,XXX是方法的参数。在这个访问模型中没有指出状态存储在什么地方,因为它假设后台是一个整体,构成一个巨大的状态集。
但 这种模型注定是过分简化的,所以会有很多的发展。发展的方向就是逐渐精细化,识别出相关的部分,把它们组织到一起。其实可以从各个框架的开发过程来看出这 种演化的过程。 Struts最早只有一个全局配置文件,现在多了一个模块的概念。WebWork是在Struts之后设计的,提供了一个所谓的package的概念,将 一堆action和interceptor组织到一起,其设计中package的extends属性看上去是不是有点眼熟。概念多了就要分模块,这一点在 面向对象之前就存在了,也符合Struts的发展历程,只是WebWork的这个extends不再是简单的模块概念了,而是一种面向对象的设计,只是 WebWork中没有实现型与名的分离,每个action名对应唯一的一个action,所以package也可以看作是一种完全静态的对象,只有一个实 例,不是吗? 我们可以做一个对应,包的namespace大概可以对应于Jsplet中的objectScope, 包名大概可以对应于Jsplet中的objectType, action对应于objectEvent, 差别在于objectScope是完全动态的,并参与Web对象管理,而package的namespace被创造出来之后只起了一个名字区别作用, Webwork的后续发展会不会在这一点上再做些文章?
再看另外一个地方。前台页面显示需要从模型中拿到数据,那模型对象是怎么管理的, Jsp本身提供了几个管理策略application, session, request, page, 几个action需要共享状态信息怎么办?状态与行为的相关就是对象化了。Webwork2没有提供对象化的手段,不知道一般人是怎么做的,将所有相关操 作都塞在一个Action里,然后通过一个扩展参数映射? 还是都从session中存取模型对象? session中的对象是不是越来越多,有没有人来管一管?

jsplet的核心是objectManager, 它利用objectFactory来创建对象,利用objectName来管理WebObject,这是与网络无关的, 这里管理的对象也不一定需要响应Web事件。
对 象如果需要响应事件, 实现IEventListener接口,在缺省实现中, Jsplet用了EventManager来管理objectEvent的响应,大致相当于xwork的工作,只是EventManager是个帮助对 象,由WebObject自己决定是否使用,而且它是每个WebObject自己使用自己的EventManager, 而不是系统全局只有唯一的一个EventManager。

整个objectManager层面都是网络无关的,当然可以单元测试。 WebEngine最终实现objectManager与web环境的关联,只是它使用了拉模式。特别是在视图jsp中调用WebEngine, 其最重要的作用是将thisObj这个变量注入到jsp模型中。this指针其实体现了对象化的很重要的特点:使用局部名而不是全局名称。
其实XWork本身也是可以脱离Web环境应用的,特别是它可以脱离View来使用,这是它的扩展性的一个来源。

在Webwork 中有一种叫做Model Driven的概念,使用Model Driven之后在OGNL表达中就可以直接使用model的属性和方法。在jsplet使用我们自己的tpl模板引擎, 其中token解析策略是thisObj的属性和方法可以直接使用,也可以通过thisObj.xx来访问,这就如同this指针的用法。


再次声明,我无意将jsplet与其它框架在实际使用效果上作对比,所分析的只是Framework整体的概念模型。数据绑定,参数和状态校验等与应用相关的功能在我们的框架中都是有着完整的解决方案的,目前不打算讨论这些。

posted @ 2005-11-15 12:32 canonical 阅读(219) | 评论 (0)编辑 收藏

   在Jsp Model 2模型中, 用户的所有请求提交给Controller Servlet, 由Controller进行统一分配, 并且采用推的方式将不同的UI显示给用户。 这种推方式在很多人看来是一种优点,因为在Struts等MVC实现中具体推送的UI可以在配置文件中配置,配置完成后还可以通过一些可视化分析工具得到 整个站点地图。在Model2模式中基本的访问格式为:
       action.do?其他参数  

我 本人从未应用过Model2模式,但与我们的jsplet框架对比,我认为这种推送方式在大多数情况下并不是什么优点。如果将一次web访问看作是一次函 数调用,则按照Model2模式,这个函数的返回情况是不确定的,需要由一个额外的配置文件来确定。而我们知道,一个返回情况不确定的函数一般不是什么良 好的设计。在我们的框架设计中,一个基本的观点是尽量将自由度暴露给实际控制它的人。实际上,在大多数情况下,页面编制人员知道应该使用哪个页面来显示数 据,他们并不需要一个额外的配置文件。Jsplet使用如下的url格式:
       视图jsp?objectName=模型对象名&objectEvent=响应事件名&其他参数
举一个具体的例子:
  
http://my.com/demo_view.jsp?objectName=/@Demo&objectEvent=test

demo_view.jsp是指定的显示页面, 其代码如下:
[code]
<%@ include file = "/engine.jsp" %>
<!-- 相当于在jsp模型中增加了一个新的变量thisObj,从而实现jsp页面的对象化 -->
<c:out>${thisObj.testVar}</c:out>
[/code]
objectName被WebEngine映射到session中的一个对象,在demo_view.jsp中成为thisObj这个变量,这就相当于java语言中的this指针,从而实现了jsp页面的对象化。

WebEngine还将objectEvent映射到一个Action响应函数并自动调用它,具体的Action代码写在一个独立的java文件或者jsp文件中。
DemoAction.jsp
[code]
<%@ include file = "/jsp_action_begin.jsp" %>
<%!
    //
 // objectName映射为thisObj, objectEvent=test映射对actTest的调用
 // 在这里增加一个actXXX函数之后,即可通过objectEvent=XXX来访问,不需要任何配置
    public Object actTest(){
  // thisObj中的变量可以在视图中使用
  thisObj.set("testVar","hello");
  return success();
 }

 // 如果存在actBeforeAction函数,则该函数在所有action函数之前调用
 public Object actBeforeAction(){
  return success();
 }

 // 如果存在actAfterAction函数,则该函数在所有action函数之后调用
 public Object actAfterAction(){
  return success();
 }
%>
<%@ include file="/jsp_action_end.jsp" %>
[/code]

在Jsplet框架中只需要注册对象,而不需要单独注册每个action。
register.jsp
[code]
<%
    WebEngine.registerType("Demo", new WebActionType("/demo/action/DemoAction.jsp"),pageContext);
%>
[/code]

与Jsplet 框架对比,Model2是对action的建模而不是对object的建模,即它相当于将objectName,objectEvent和 view.jsp绑定在一起定义为一个访问点action.do,绑定过程中需要一个配置文件来固化view.jsp和action之间的联系。因此, Model2并没有完全分离view和model,它隐含假定着objectName只具有一个objectEvent, 并且绑定了一个具体的view(出错页面除外)。
例如, 我们需要两个不同的view来显示同一个数据,则在Model2程序中可能需要配置两个独立的访问点,而在我们的框架中只需要使用两个不同的url:
a_view.jsp?objectName=/@Demo&objectEvent=test
b_view.jsp?objectName=/@Demo&objectEvent=test
同样的web程序甚至可以在前台通过XMLHTTP方式来调用而不需要额外配置!

在Jsplet框架中采用的是对象化的方式而不是Action化的方式,因此存在着多种面向对象的扩展,而所有的扩展都直接体现在url格式的细化上,一切都在阳光下。
  在Jsplet中objectName是WebObject的名称,在全系统内唯一,其格式定义为:
objectScope@objectType$objectInstanceId
1. 对象类型objectType
  我们需要注册的是对象类型而不是完整的对象名,一个对象类型可以对应于无数个完整的对象名,例如我们注册了Demo类型的WebObject, 则
objectName=/@DemoobjectName=/left/@Demo对应的处理文件都是DemoAction.jsp。
2. 对象生命周期控制objectScope
  objectScope为WebObject所在的域,其格式符合Unix路径命名规范。JSP模型本身支持一些预定义的对象域,包括page, request, session, application等。但为了能够反映现实世界中的对象组织结构,对象域必须是允许自定义的。objectScope被组织成一个树形结构,这是一个 基本的控制结构,其控制策略为
     同时存在的对象域之间必须存在线性序关系(order)
  当系统访问某一对象时,如果该对象所在的对象域不能和现有对象的域处在同一"路径"下(即当对象域之间不能建立父子关系时),系统就会自动销毁不兼容路径 分支下的所有对象。 这种精细的控制策略保证了系统的可扩展性,因为模型上可以保证始终只有一部分对象被创建。
对象转移                                                           系统动作 
/main/@MyObject ==> /main/left/@OtherObject                       无
/main/left/@OtherObject ==> /main/@MyObject                       无
/main/left/@OtherObject ==> /main/left/@MyObject                  无
/main/left/@OtherObject ==> /main/right/@MyObject                自动销毁/main/left子域下的对象,如/main/left/@OtherObject
 
3. 对象实例标识 objectInstanceId
 如果在某一对象域中需要包含多个同一类型的对象,可以通过objectInstanceId来加以区分,这样在同一个页面上我们可以使用多个同样类型的对象。

Jsplet中另外一个扩展是通过事件路由来支持jsp子页面的对象化。例如
http://my.com/demo_main.jsp?objectName=/@Main&eventTarget=/@Sub&objectEvent=test
如果指定了eventTarget参数,则objectEvent由eventTarget对应的对象来响应。
在jsp文件内部我们可以通过include语法来引入子对象,例如
   <jsp:include page="
sub_view.jsp?objectName=/@Sub" />
(注:我不是非常清楚Tapestry具体是如何实现对象化的,熟悉Tapestry的朋友可以介绍一下)

在Jsplet中可以通过配置文件来支持对Action的interception, 例如
[code]
<factory>
<listener-filter  class="global.LogFilter" />
<post-listener class="global.CommonActions"/>

<type name="Demo">
 <!-- 如果未指定object, 则缺省为WebObject类型 -->
 <object class="demo.MyWebObject" />
 <listener>
  <filter event="query*|select*" class="demo.LogFilter" />
  <url-listener url="/demo/DemoAction.jsp" />
  <url-listener url="/demo/DemoAction2.jsp" />
 </listener>
</type>

</factory>
[/code]
在上面这个配置文件中,DemoAction.jsp和DemoAction2.jsp是chain关系,即事件响应的传播模型中,如果event没有被标记为stopPropagation,就会传递到下一个listener。

综上所述,可以看到在目前多变的需求环境下,Model 2已不是一种非常完善的Web程序模式,一些重要的设计需求在Model 2模式的推方式中很难得到合适的表达。

posted @ 2005-11-15 12:31 canonical 阅读(333) | 评论 (1)编辑 收藏

在witrix平台中访问数据库最直接的方法是使用edu.thu.db.SQL类。基本用法如下:
//  设定数据库连接参数, 连接可以通过java.sql.DriverManager 和

//javax.sql.DataSource等多种方式建立,并支持数据库连接缓冲池。
TransactionMode db = new TransactionMode("default"); // 设定数据库连接参数
SQL sql = SQL.begin().select().field("id")
                     .from().table("other_table")
      .where().like("name","a%");
   .end();
int n = SQL.begin().select().countAll()
                   .from().table("my_table")
       .where().gt("value", new Integer(3)) // value > 3
            .and().in("type", new String[]{"a","b"})  // type in ('a','b')
         .and().in("data_id",sql)  // data_id in (select id from other_table where name like 'a%')
      .end().query(db).intValue();

在SQL类的设计中体现了三个设计原则:
1. 正交化的流式设计
2. 参数对象化
3. bug-free设计

首先,SQL类将构造SQL语句,连接数据库以及查询结果类型转换分解成了三个正交的部分。
在一般的数据库编程中,我们需要如下访问方式:
String sql = "select count(*) from my_table where value > ?";
Connection conn = getConnection();
PreparedStatement stmt = null;
try{
     PreparedStatement stmt = conn.prepareStatement(sql);
  stmt.setParameter(1, valueLimit);
  ResultSet rs = stmt.executeQuery();
  rs.next();
  int ret = rs.getInt(1);
  // ...
}finally{
 try{
  if(stmt != null)
   stmt.close();
 }catch(Exception e){
     e.printStackTrace();
 }

 try{
  conn.close();
 }catch(Exception e){
     e.printStackTrace();
 }
}

从 以上的例子中,我们可以注意到,在普通JDBC编程中,设置SQL语句的参数,建立数据库连接,取得结果集中的结果并转化为合适的格式这三者之间是交织在 一起的。特别是打开连接需要配对的关闭连接语句,造成整个程序的流程不是线性的, 因为我们不能说建立连接之后就可以不再管连接的事情了,我们必须记住在做完所有其他事情之后还要关闭连接。    通过一系列的封装对象,SQL类实现了一种正交化的流式设计,其分解模式如下:
      SQL.begin().拼接SQL语句.end().建立连接并运行SQL语句.转化结果()
注意在SQL语句执行之后是不需要显式关闭连接的。

SQL类的第二个设计要点是参数对象化。在witrix平台中,实际运行SQL语句的引擎函数是
 IDbEngine.execute(String sqlText, List sqlParameters, int resultType, int concurrency);
这 里sqlText, sqlParameters等都是参数,但是在应用中构造这些参数的过程很复杂,并且非常灵活,一般的Util类(静态Utility函数)无法提供有效 的简化。 所以构造SQL语句这个过程不是通过util类完成的,而是通过一个专用的SqlBuilder对象。SQL的基本思想是将sql语句纳入java程序框 架,使得sql语句成为程序中可控制的部分。首先SQL类将sql文本与sql参数封装为一个完整的对象,使得sql语句的重用成为可能。其次, SqlBuilder类通过一种可控制的方式构造sql语句(所有的关键字都对应于一个函数),整个过程与直接书写sql文本类似,但函数封装使得我们能 够在同一行上指定sql文本中用到的参数,而不是象jdbc里那样,集中指定参数。同时SqlBuilder支持面向java语言的扩展,如直接支持 java集合类型等,从而大大简化了sql语句的构造,因为一般sql拼接中最混乱的部分就是牵涉到循环与判断。
  参数对象化的方法还可以应用于那些具有大量缺省参数的地方。在SQL类中,如果我们希望以scroll insensitive的方式选出数据,调用方式如下:
  SQL.begin().select().star()
             .from().table("my_table")
   .end().scrollable(true).list(db,3,100);
如果我们希望利用Statement.cancel()特性,我们可以指定cancelMonitor参数
   SQL.begin()....end().cancelMonitor(monitor).query(db).listValue();

SQL 类的第三个设计要点是bug-free。jdbc中最常出现的错误是忘记关闭连接造成资源泄漏,在SQL类中,连接只在需要时才从缓冲池中获取,当数据库 操作完成(无论成功或失败)时,数据库连接会被自动关闭(或返回连接池),并自动处理提交和回滚的情况。整个程序代码中一般没有需要显式关闭连接的要求, 从而极大的降低了资源泄漏的几率,避免了这个错误的出现。这就如同java没有要求程序员显式释放内存,从而在绝大多数情况下避免了memory leak的bug一样。

posted @ 2005-11-15 12:30 canonical 阅读(254) | 评论 (0)编辑 收藏

关系数据库的关键之处在于关系的分解,在数据库中只定义了数据之间的两两关系,与应用相 关的更复杂的数据关系需要在运行时通过动态join来构造出来,即这些关系储存在程序中而不是数据库中。实际上,关系数据库的一个隐含的假定是数据之间很 少关联,而在实际应用中单表和主从表也正是最常出现的情况。当一个应用频繁需要大量表的连接操作的时候,往往意味着关系数据模型的失效,此时我们将不得不 放弃数据的无冗余性,需要通过预连接来构造实例化视图(Material View),将数据之间的复杂关系固化并明确定义出来。 在数据仓库里,抽象的讨论star schema和snowflake schema哪个更优越是一个毫无意义的问题。 应该聚合到什么程度,需要根据数据应用的具体情况而定。
    关系数据库本身定义的是数据之间的两两关系,缺乏一些全局数据访问手段。而数据仓库的一个基本概念是数据空间,即可以通过全局坐标来直接访问数据,而不是 通过两两连接来访问数据。在数据仓库中最重要的就是时间维度,因为这是所有数据所共享的一个坐标维度。我们可以将两个发生在同一时间点上的数据直接并列在 一起,而无论它们之间是否定义了关联(relation)。
 关系数据库的基本数据访问模式如下:
 select 属性列表            
 from 表A, 表B
 where 表A.data_id = 表B.id
 and 表B.attr = 'A'
 在数据仓库中 " from 表A, 表B where 表A.data_id = 表B.id "这一部分将多个多个数据表和表之间的关联条件放在一起定义为所谓的主题。
 而 表B.attr = 'A' 这一部分就从where子句中分离出来作为坐标条件。
    在数据仓库中建立时间坐标有两种方式,对于发生在时间点上的事件我们直接建立点坐标,通过his_date字段来表示,而对于延续一段时间的状态数据,我们可以建立区间坐标,通过from_date和to_date两个字段来表示。

posted @ 2005-11-15 12:29 canonical 阅读(305) | 评论 (0)编辑 收藏

 Unix中的Pipe模型被认为是Unix最美妙的思想之一: 大量独立的小工具通过管道组合在一起,可以构成非常复杂和多样化的功能。例如:dir|sort。 这是一种功能正交分解的做法,其隐含的一个基本假定是这些小工具之间具有完全的对称性,即Pipe模型本身没有限制哪些工具可以组合在一起,也没有限制这 些工具组合时的顺序。当系统逐渐复杂起来,对称性发生破缺(Symmetry Broken),则出现了Layer模型,即在不同层次上的对象不能互换, 而同一层次上的对象仍可以互换, 例如协议栈。更加复杂的系统中,完整的重用一个对象变得越来越困难,组件技术通过接口将对象分解为正交的子部分,最终构成一个网状模型。

posted @ 2005-11-15 12:27 canonical 阅读(170) | 评论 (0)编辑 收藏

cocoon的文档中有这样一段话:
Traditional Web applications try to model the control flow of a Web application by modeling the application as a finite state machine (FSM). In this model, the Web application is composed of multiple states, but the application can be only in one state at a time. Any request received by the application transitions it into a different state. During such a transition, the application may perform various side-effects, such as updating objects either in memory or in a database. Another important side-effect of such a transition is that a Web page is sent back to the client browser.

    Servlet模型提供的正是一个最基本的基于IO的FSM模型:应用程序的状态变量存储在session中,应用程序根据用户请求更新session中 变量的值。这里一个隐含的假设是session中的变量是不相关的,因为servlet模型中没有提供任何机制来同时操纵一组相关变量,例如我们在 session中存放了三个变量name, title, data, 如果我们希望删除这三个变量,我们必须通过三次独立的函数调用来完成,servlet模型本身并不知道这三者之间的关联关系。
    当web应用程序逐渐变的复杂起来,这个最简单的FSM模型就显得力不从心了。因此发展出了MVC模型(Model-View-Controller), 这是对有限状态机的一个精细化。首先我们识别出session,request中的变量之间存在相关性,而且变量之间的地位也是不平等的,某些变量的改变 将直接导致另外一些变量的改变。因此变量根据相关性被聚合起来,构成很多对象。应用程序的状态不再由一个个独立的变量构成,而是由具有更丰富语义的对象构 成。在大的结构方面,一些基本的对象被分离出来,构成一个核心,即model层, 而外围的变量被分割在不同的view中。 在流行的struts和webwork等MVC框架中,变量的聚合都定义在action层, 各个相关的action并没有汇聚成一个具有独立意义的对象,似乎仅仅做到了model层和view层的分离,在model层内部并没有建立合适的模型, 即struts和webwork等建立的MVC模型中隐含假定整个model层内部是没有结构的(注,我对struts和webwork的了解限于简单介 绍文档,这里的说法可能并不准确)。一些更加精细的MVC架构直接支持model层的分解,即model层由一系列不相关的对象构成,每个对象具有从属于 自己的action。沿着这个复杂性发展的级列继续下去,我们可以知道,当对象之间的交互变得更加复杂的时候,我们需要框架本身能够直接支持model层 对象之间的相关性。最简单的控制关系是树形结构,即父节点控制子节点,父节点销毁的时候子节点自动销毁。这样就构成所谓的HMVC (Hierarchical MVC)模型。在这个模型中,model层由一系列的对象组成,而且这些对象被分割到不同的package中,组成一个树形结构.

posted @ 2005-11-15 12:26 canonical 阅读(231) | 评论 (0)编辑 收藏

   控制论的基本哲学是:对于一个未知的黑箱系统,仍然可以根据观察建立控制模型,简言之,即控制有理。无论是物理系统,生物系统,社会系统,其控制的机理是 一致的。这里所强调的是一种广义的建模,即我们并不寻求该系统本质上的物理模型,而是寻求一种"有用"的模型。实际上,在数学上早已准备好了多种广义模型 系列,最典型的Taylor展开可以建立不同级次的多项式模型,我们所要做的只是根据不同的需要去做拟合。

posted @ 2005-11-15 12:25 canonical 阅读(173) | 评论 (0)编辑 收藏

   关系数据库的理论基础是集合论,而集合的基本定义就是不重复的一组元素。而xml数据库方面尚缺乏相应的理论来消除数据冗余性。
   关系数据库能够成功的另外一个重要原因是它采用平面表形式,而应用中大量使用的正是平面表,所以数据库表在很多时候是数据的最适表现形式,使用xml表达 只会增加不必要的复杂性。平面表的基本假设是所有条目的结构都是一样的(具有一个header),而xml表示形式本身不存在这样的假定,因此很多时候无 法根据数据的shape来做有效的优化。当然xml schema等技术正在快速发展的过程中,当相应的元数据描述和使用技术逐渐成熟之后,xml的处理方式会得到本质的提高。
   xml技术是目前元语言的代表,它最重要的技术优势在于它是人与机器都能轻易理解的语言,是人机共享的信道! 目前它并不适合在应用程序中表达复杂的多维关联。特别是目前多数操纵xml的API都是面向文档的,所存取的数据类型都是字符串,更造成了程序应用上的困 难。

posted @ 2005-11-15 12:23 canonical 阅读(242) | 评论 (0)编辑 收藏

一个技术的成功,在于最终占据了某个概念。当我们应用到此概念的时候,首先想到的就是这个技术实现,久而久之,形成一个自我证明的过程。而有些技术却是在 其位无能谋其政,实在是让人不得不为它扼腕叹息呀。jsp tag正是这样一种技术。有些人认为jsp tag只是jsp的一种扩展,只是一种syntax suger, 这正反映了此技术所面临的一种困境。这里指出一些jsp tag的设计缺陷,并无贬低这种技术的意图,只是希望抛砖引玉,引发大家对这种技术改进的探讨。
引用:
jsp tag是服务器端的扩展标签机制,它是一系列java服务器端技术的基础。但其设计之初的几个重大缺陷已经使得这种技术不堪重负。  

对比dotNet平台我们可以知道,需要一种后台标签机制,jsp tag是唯一的标准(JSF等机制都依赖于此),可它的设计给所有希望基于它开发的开发人员造成了巨大的困扰。实际上我对这个技术感到很失望,当然我们提 出了相应的替代方案。在我们的开发框架中使用的是重新设计的一套与网络无关的xml动态标签机制。我的观点是基于jsp tag技术,无法开发出与dotNet的便捷程度相当的服务端技术,所以这是它作为标准的罪过。jsp tag不应该是jsp的补充,它搭上了xml这条大船,应该去走自己的路,而不应该成为应用上的鸡肋。
引用:
1. jsp tag与jsp 模型紧密绑定,使得业务逻辑很难抽象到tag中。而且脱离了jsp环境,在jsp tag上的技术投资将一无是处。  

这里说业务逻辑可能是有些不妥,容易引起误解。因为我的工作做在中间件层,所以我的原意是基于jsp tag开发一系列的扩展技术,比如缓存等。我们的xml标签技术是与jsp模型无关的,在前台用于界面渲染,在后台用于工作流描述。而且很方便的就可以与 其它xml技术结合,比如集成ant。

引用:
2. jsp tag的编码逻辑非常繁琐, 特别是写loop和容器类标签的时候。在2.0之前不支持从tag本身产生tag更是应用上的主要障碍。  

这绝对是个重大问题,试问多少人自己去开发jsp tag呢,多半是用用别人的成品。编制困难其实就是否定了界面元素的重用。很多人推崇Tapestry, 其实如果jsp tag技术方便一点,何必建立一个完全不同的模型呢。

引用:
3. 使用将xml标签的属性直接映射到对象属性的方法造成tag对象是有状态的,不得不通过丑陋的pool机制来解决性能问题。
而且性能问题直接限制了大量小标签的使用。  

这是一个现实的困难,一个系统设计师必须考虑。

引用:
4. jsp tag是一种完全动态化的设计,大量可以在编译期进行的优化都无法进行,基本上所有的运算都是在运行期发生,限制了性能的提高。  

我们的xml标签技术是先编译再运行的,加上无状态设计,在性能上可以得到控制。我的朋友hotman_x是个C++和js高手,在他的强烈要求下,我们的xml标签还增加了一个多次编译的机制。

引用:

5. 虽然最近的版本已经支持xml格式,但对于xslt等的集成很不到位,例如现在无法使用xslt对jsp文件进行界面布局。

最简单的
<web:template src="test.tpl" xslt="layout.xslt" />
<web:mytag xdecorator="face.xslt">
...
</web:mytag>

引用:
6. jsp tag要求使用自定义标签名,而无法对已经存在的html标签进行enhance, 造成无法方便的在可视化编辑器中进行编辑。  

Tapestry就认为它比较好。我们的xml标签机制也支持属性扩展。

引用:
7. EL表达式竟然不支持调用对象函数

很多人因此觉得OGNL比较好。我们的机制中是对EL做了一定的增强。我不喜欢OGNL, 过于复杂了。

posted @ 2005-11-15 12:21 canonical 阅读(396) | 评论 (0)编辑 收藏

仅列出标题
共18页: First 上一页 10 11 12 13 14 15 16 17 18 下一页