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 閱讀(234) | 評論 (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 閱讀(236) | 評論 (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 閱讀(353) | 評論 (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 閱讀(277) | 評論 (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 閱讀(327) | 評論 (0)編輯 收藏

           Unix中的Pipe模型被認為是Unix最美妙的思想之一: 大量獨立的小工具通過管道組合在一起,可以構成非常復雜和多樣化的功能。例如:dir|sort。 這是一種功能正交分解的做法,其隱含的一個基本假定是這些小工具之間具有完全的對稱性,即Pipe模型本身沒有限制哪些工具可以組合在一起,也沒有限制這 些工具組合時的順序。當系統逐漸復雜起來,對稱性發生破缺(Symmetry Broken),則出現了Layer模型,即在不同層次上的對象不能互換, 而同一層次上的對象仍可以互換, 例如協議棧。更加復雜的系統中,完整的重用一個對象變得越來越困難,組件技術通過接口將對象分解為正交的子部分,最終構成一個網狀模型。

          posted @ 2005-11-15 12:27 canonical 閱讀(179) | 評論 (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 閱讀(238) | 評論 (0)編輯 收藏

             控制論的基本哲學是:對于一個未知的黑箱系統,仍然可以根據觀察建立控制模型,簡言之,即控制有理。無論是物理系統,生物系統,社會系統,其控制的機理是 一致的。這里所強調的是一種廣義的建模,即我們并不尋求該系統本質上的物理模型,而是尋求一種"有用"的模型。實際上,在數學上早已準備好了多種廣義模型 系列,最典型的Taylor展開可以建立不同級次的多項式模型,我們所要做的只是根據不同的需要去做擬合。

          posted @ 2005-11-15 12:25 canonical 閱讀(183) | 評論 (0)編輯 收藏

             關系數據庫的理論基礎是集合論,而集合的基本定義就是不重復的一組元素。而xml數據庫方面尚缺乏相應的理論來消除數據冗余性。
             關系數據庫能夠成功的另外一個重要原因是它采用平面表形式,而應用中大量使用的正是平面表,所以數據庫表在很多時候是數據的最適表現形式,使用xml表達 只會增加不必要的復雜性。平面表的基本假設是所有條目的結構都是一樣的(具有一個header),而xml表示形式本身不存在這樣的假定,因此很多時候無 法根據數據的shape來做有效的優化。當然xml schema等技術正在快速發展的過程中,當相應的元數據描述和使用技術逐漸成熟之后,xml的處理方式會得到本質的提高。
             xml技術是目前元語言的代表,它最重要的技術優勢在于它是人與機器都能輕易理解的語言,是人機共享的信道! 目前它并不適合在應用程序中表達復雜的多維關聯。特別是目前多數操縱xml的API都是面向文檔的,所存取的數據類型都是字符串,更造成了程序應用上的困 難。

          posted @ 2005-11-15 12:23 canonical 閱讀(270) | 評論 (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 閱讀(418) | 評論 (0)編輯 收藏

          僅列出標題
          共18頁: First 上一頁 10 11 12 13 14 15 16 17 18 下一頁 
          主站蜘蛛池模板: 新田县| 哈巴河县| 临西县| 东至县| 灵寿县| 南投市| 陆丰市| 宽城| 湘阴县| 泽普县| 象山县| 安远县| 邹平县| 新安县| 金沙县| 大方县| 云梦县| 黄石市| 化州市| 滨州市| 济宁市| 鄂州市| 鞍山市| 银川市| 会东县| 遂川县| 临西县| 邵阳市| 门源| 唐河县| 泾源县| 嵊泗县| 武穴市| 彭山县| 涟水县| 巢湖市| 安陆市| 化州市| 永城市| 宜阳县| 瑞安市|