<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

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

     元數據(meta)是描述數據的數據。它所描述的有一部分是數據本身的特性,如字段的長度,精度等,另外一部分描述的則是我們使用這些數據的可行方式和目的等。使用meta可以在程序中更加清楚的表達出我們的意圖。例如現在需要在界面上顯示一個列表,我們的意圖未必是要在界面上顯示指定的字段A, 字段B,字段C對應的列,而是"顯示那些應該顯示在列表中的字段"。這一看似同義反復的表述,如果采用元數據表達,則成為 <ui:PageTable fields="${dsMeta.listableFields}" />。通過使用元數據,我們可以做到系統中眾多的功能可以共用實現,即通過同一個頁面應用不同的meta則得到不同的最終展現,而后臺一個通用的DaoWebAction通過使用meta可以完成對所有實體的操作。這也可以看作是一種復雜的策略模式的應用。

    posted @ 2007-08-19 13:39 canonical 閱讀(1204) | 評論 (2)編輯 收藏

      ORM(Object Relational Mapping)技術為什么是有效的?對這個問題一般的答案是ORM解決了面向對象技術和關系數據庫之間的阻抗匹配問題。但是任何一種成功的技術,它的支持理由都不會是單一的。在Witrix平臺的實踐中,ORM的如下幾個特性是關鍵性的:
      1. 主鍵和對象之間的一一對應關系。在Web應用中,前臺瀏覽器持有的只能是對象的某種表示, 因此一種locator機制是最基礎的要求。
      2. Container結構。Container所擁有的信息包括其所有元素以及元素之間的關系。因為Container具有全局知識,所以它可以解決對象圖中的循環依賴問題。正是因為session中一級緩存的存在,才能在實體延遲加載的情況下保證對象引用的唯一性,保證a.b.c.a == a。在程序設計中,所有支持對象圖的Container結構都是non-trivial的,都必然是有價值的。例如spring容器在配置管理方面最重要的價值就在于可以管理循環依賴的對象創建過程。而在witrix平臺的前臺所定義的ControlManager管理器其核心作用就在于協調前臺控件之間的消息響應依賴關系。從spring的配置文件可以清楚的看出,bean的聲明過程是順序進行的,但是bean的創建過程是非順序結構的。在數學上,我們說系統的拓撲(topology)發生了變化。
       A a = new A();  B b = new B();  a.setB(b); b.setA(a);
      3. 對象作為復雜屬性的集合。關系數據庫中保存的都是原子性數據,每一列都是不可再分解的原始數據類型,數學上稱之為標量(scalar). 而ORM引擎返回的直接就是嵌套的復雜數據類型,因此不再需要一個額外的造型過程.雖然總是返回全部數據列不是很優化,但是這種強制性的較粗的處理粒度使得前臺程序可以有更多的選擇自由.
      4. 對兩兩關系的內蘊表達及充分利用.關系數據庫中所保存的是系統分解后的表示,即關系被分解了而不是被表達了,外鍵對數據關系只起到一種約束作用,它對于查詢語句的構建并沒有直接的影響.所有數據之間的關系都必須在查詢的時候明確指定出來,即調用者必須擁有數據關系的知識,而不是數據本身擁有這些知識.在如下的sql語句中
       select * from a, b
        where a.fldA = b.fldB
        and a.fldC = 1 and b.fldD = 2
    a.fldA = b.fldB 可以稱為關聯條件,而a.fldC=1可以稱作是坐標條件.SQL的復雜性很大程度上來源于我們頻繁的需要在各處指定完全一樣的關聯條件而無法把它們抽象成可復用的組分.在ORM所提供的對象空間中,對象之間的兩兩關聯只要指定一次,就可以在增刪改查等各種操作過程中起到作用,特別是在對象查詢語句中,可以通過兩兩關聯自動推導出多實體之間的關聯關系,雖然推導出的結果未必是最優化的.
      select from a where a.fldC = 1 and a.b.fldD = 2
       在Witrix平臺中,我們做了大量的工作以確保對象上的復合屬性(例如a.b.fldD)和本征屬性(例如a.fldC)在使用上是完全等價的.這些工作的結果并不僅僅是減少了一些應用層的代碼量,它使得系統結構發生了深刻的變化.復合屬性把單表模型推進到了業務主題模型,使得單一業務對象可以聚集某一范圍內的相關結構信息,這才使得witrix的模型分解技術成為可能。因此在我們看來,HQL是hibernate價值的集中體現.
       5. POJO提供了純粹的first class的持久化結構空間.采用POJO結構可以充分利用現有語言及開發工具中的一系列基礎設施,大大降低了持久化結構的構造成本.而透明的get/set操作使得我們可以完全基于相對知識對持久化結構進行變換,在完全不依賴外部環境信息(例如數據庫連接和ResultSet界面)的情況下解決系統的主要業務結構問題.這一切成為可能在技術上都源于AOP(Aspect Oriented Programming)所引入的重新詮釋的能力,它使得我們可以將對象上的某種相對操作重新詮釋為對數據庫的相應操作.
       http://canonical.javaeye.com/blog/37064
         6. Entity具有活動能力.Entity并不是完全被動的數據容器,而是可以定義復雜動作的對象.在Witrix平臺中,后臺程序大致具有如下結構
            Entity  ---- 結構問題
          Handler ---- 業務動作定義
          BizFlow ---- 動力學問題
     Handler類似于J2EE中傳統的Service層,只是一般實現的方法要少的多.而BizFlow是某種結合了界面表示的流程引擎.基于實體結構使得系統在細粒度處具有某種活動能力,便于我們構造一些局部結構來解決問題,因而也就緩解了大量操作在Service層的堆積過程,有利于維護系統整體結構的對稱性.
        -----------    ==>   -------------|--
        -----------                               |--
        
        通過對于ORM技術的理論分析,Witrix平臺采取了一些和一般J2EE架構不同的設計.實際上目前J2EE架構下的常見的DAO模式在使用ORM技術的情況下往往不是合適的選擇,因為DAO的一般設計是封裝某個實體相關的操作,它直接破壞了ORM的container結構。原先我們只需要EntityManager.get(entityClass, id)這一通用方法既可得到各種數據實體對象,而現在需要對每種實體調用不同的Dao函數,顯然這是對系統結構的重大破壞。在Witrix平臺的設計中沒有獨立的DAO層,它通過通用的EntityDao統一完成所有對象的存取過程,而不是每個XXXManager繼承公共的Dao類。即整個系統架構中盡量維護數據存取過程的統一性而不是實現它的分散化。
      在Witrix平臺的Workflow引擎,Wiki引擎等模塊的設計中,IWorkflowStore和IWikiStore等類的設計類似于DAO模式,是對存取方式的一種封裝。在比較復雜的模塊中,對于存取邏輯做出一定的封裝是需要的。但是注意到Store類的設計和實體框架的設計相比,其結構可分解性要相差很多,它基本上只提供對外的服務接口。如果我們能夠對于文件系統等存儲設施作出充分多的工作,我們一樣可以對于非關系數據庫的某些存取形式完成Container結構,只是這個工作量過大,而我們一般并不需要對非通用的存取結構掌握如此充分的知識。
         實體結構隱含的擴展了系統的同時性視圖,a.b.c.a == a 所隱含表達的事實是a,b,c是同時存在的.http://canonical.javaeye.com/blog/33797 在某些時候,例如當我們需要將系統結構順序化,序列化的時候,這種同時性會成為一種障礙.因此Witrix平臺中數據同步所使用的ETL(Extract Transform Load)引擎是基于表結構(分解后信息)的,而不是基于實體結構(關聯信息)的.實際上,關系模型在某種意義上是系統分解后的必然結果,因此隨著我們對系統的理解的粒度要求越來越精細,很可能最終需要我們明確意識到關系對象本身的存在性,最終實體模型會非常近似于關系模型.只不過在實體模型級列中我們選擇的余地更大,關系模型可以看作是它的某種極限.理想的情況是在不同的時刻我們可以使用不同的關系抽象,只是受限于目前的實現技術,在系統構建時刻基礎的關系結構往往就被固化下來.

    posted @ 2007-08-13 00:25 canonical 閱讀(1051) | 評論 (2)編輯 收藏

       JSF(Java Server Faces)技術從發布時間上看已經是一種比較古舊的技術了,但是目前仍未能成為主流的開發實踐。從我知道這種技術開始, 我對它的判斷就與我最早對于EJB的判斷一樣, 它們都在某種程度上捕獲了真正的需求,但是因為它們自身詭異的技術路線.我很懷疑是否這些標準制定者故布疑陣, 便如Microsoft的OLE技術一樣, 故意拋出一個錯誤的方向, 將大批組件開發商帶入死局.
       JSF技術是一種雙重的存在:它首先是一種標準,然后也提供了一種缺省的實現。但是從這兩方面,我都無法看到JSF的未來。
       從設計上說,強類型的視圖模型對象層與Witrix的架構設計原則嚴重沖突。Witrix的基本架構是瀏覽器和后臺服務器通過具有顯明語義的url實現兩分,這也是所謂REST風格的一種內在要求。隱蔽了鏈接的技術破壞了基本的web超鏈模型. 為了獲得那么一點點結構控制能力, 做出這樣的抽象是不合適的.JSF的配置模型繼承了structs的傳統,仍然是那樣的冗長繁雜。我們是否真的需要這些配置文件,還是希望像ROR那樣在代碼中直接完成一切?
       不能在標準的瀏覽器中預覽. 可以說創造了一個JSF IDE的市場, 但是這無疑是一個無聊的市場. 現在有一些備選的方案, 如Facelets, 使得jsf可以采用屬性語法, 但是只要想想僅僅為了這么一點小小的修正所需要付出的開發量就足以讓人崩潰。
       JSF提供了組件級別的事件響應機制,因此似乎是AJAX應用的理想場所.但從Witrix平臺的開發實踐來看,JSF對于AJAX的使用是受限制的,有著很大局限性的.組件事件響應并不一定要采取JSF那種體系結構.
       從實現角度上說,基于jsp tag可以說是JSF的致命弱點之一. jsp tag從設計之始就一直是未經過實踐考量,其設計無法支撐復雜的控件架構. 特別是早期JSF與標準的JSP tag不能互通實際上是明顯的設計缺陷, 而且性能問題是內置在該設計中的. 現在雖經多個版本的不斷補救, 但是為了兼容性, JSP Tag負擔過重, 它始終是基于文本處理模型,實際上不可能有什么本質性的進步. JSP tag模型過分孱弱必然造成JSF設計中大量處理過程堆疊到界面對象層,更加劇了JSF的模型復雜度和性能瓶頸。 實際上根據Witrix平臺中tpl模板技術的設計經驗,大量界面構建過程是可以在模板層以直觀的方式完成的,而不需要借助視圖模型對象。
       所有問題的一個集中體現就是增加一個新的JSF組件絕對不是一件平凡的事情.如果有一天這個問題可以得到解決,那時的JSF從思想和實現上都必然和現在的JSF有著本質性的區別.

    posted @ 2007-07-29 23:43 canonical 閱讀(1333) | 評論 (7)編輯 收藏

      REST(Representational State Transfer) 是Roy Thoms Fielding在其博士論文中所提出的一種架構風格(Architectual Style)。http://roy.gbiv.com/pubs/dissertation/top.htm  http://www.redsaga.com/opendoc/REST_cn.pdf 可以說它也體現了整個互聯網架構的基本設計原則。隨著AJAX等技術的發展,互聯網的資源語義逐漸得以恢復,最近對于REST的討論也熱烈起來。http://www.ibm.com/developerworks/cn/web/wa-ajaxarch/
      在Fielding的論文中對REST有如下陳述:
    The name “Representational State Transfer” is intended to evoke an image of how a well-designed
    Web application behaves: a network of web pages (a virtual state-machine), where the
    user progresses through the application by selecting links (state transitions), resulting in
    the next page (representing the next state of the application) being transferred to the user
    and rendered for their use.
      點擊超鏈接之后,服務器端返回資源的某種表示(Resource Representation), 客戶端的狀態(Representational State)隨之發生遷移(transition),在服務器端返回的表示中存在著到其他狀態的遷移鏈接,使得我們始終自動具有進一步遷移的能力(這和ajax中所謂返回純粹數據其實是不同的). 這種圖景其實也正是Tim Berners-Lee最早所設想的web的圖景。因為REST是對互聯網架構設計的一種抽象,因此所謂的Restful其實就是盡量符合現有Web標準。從概念上說,REST所關注的主要還是分布式資源信息交換,而不是對復雜的業務邏輯進行抽象。遵循REST將會使整個互聯網受益,確保路由器,緩存,代理,瀏覽器,服務器等各個組件可以協同工作,它的意義并不是針對單個應用程序的。不過與witrix體系架構相對比,我們還是可以發現REST架構風格對于一般web程序的參考價值。
       1. 通過唯一的,確定的url來標定可訪問的資源。url定義了后臺資源的訪問界面,明確區分了瀏覽器和服務器兩個分離的狀態空間。這種兩分的架構約束是witrix平臺最重要的設計原則。在witrix平臺中,Jsplet, BizFlow, PageFlow,AuthMap等技術完全體現在url的精化設計上,系統中所涉及到的所有關鍵概念都對應于url中的明確組分。而JSF等技術通過對象封裝模糊了資源的訪問界面,迫使我們只能通過一個錯綜復雜的對象包絡來理解系統的交互過程。
       2. REST強調整個交互圖景中所有需要的相關信息都是in band的,而且語義上不同的部分都對應于特定的語法上不同的部分。例如為了保證url的不透明性和穩定性,一些信息通過http協議的header來傳遞。這里強調的語義自明性實際上是脫離具體知識體系的形式上的可區分性。在現有的服務器端程序中, 因為直接接觸到的是已經解析好的parameter集合, 因此Witrix平臺中關注的是在參數集合中識別出特定的形式結構, 這通過EngineURL對象實現.
       3. HTTP中明確區分了GET/POST/PUT/DELETE四種標準操作, 并對它們的語義進行了精確的限定. 而所謂的RPC(Remote Procedure Call)與此是不同的. RPC上承載的方法數可以是無限多的,但是這種無限多的操作反而從某種層面上說是簡單的,是對稱的,沒有可區分性。而在REST中,在確定資源這一限制下,我們可以區分出GET/POST/DELETE/PUT這四種有限但是不同的語義。 是否這四種語義構成完備的操作空間?從某種意義上說, 這四種操作覆蓋了資源的整個生命周期, 它自然滿足了某種完備性. 但是抽象意義上的完備性并不意味著它在物理層面上也是完備的. 我們都知道二維空間是完備的,但是二維描述并不是三維空間的合適表達. 在Witrix體系下,WebAction所提供的完備的操作集合包括Query, ViewDetail, Update, Add和BizAction.
    BizAction是個特定的擴展,所有不便于直接歸類到CRUD操作的操作都可以歸類到這一Action的名義下. Witrix架構中把CRUD看作是一個更大的Action空間的一個子空間, 對此子空間的結構進行了細致的劃分, 所關注的重點是對部分信息的更明確的表達, 而不是對程序整體的建模.
       區分GET/POST/PUT/DELETE四種操作, 最重要的意義在于定義了GET和其他操作的區別. http://www.w3.org/DesignIssues/Axioms.html
     a. in HTTP, GET must not have side effects
     b. in HTTP, anything which does not have side-effects should use GET
       在GET這種語義下, 才可能建立獨立的cache組件, 而正是因為cache的存在, 才使得web成為infomation space而不是computing program. 而在Witrix平臺中, 很多通用機制的建立(例如精確到數據行的訪問權限)都需要對于CRUD做出精細的區分, 而不僅僅是識別出GET操作.
      4. REST中雖然定義了具有概念穩定性的url, 但是因為操作集合有限,而且強調服務器端的無狀態性, 因此一般認為這種結構并不是面向對象的. 不過,在我看來,面向對象首先意味著一組相關性的聚集, 實際上從語義層面上看, REST與witrix平臺的jsplet框架非常接近, 最大的差別在于服務器端明確定義的thisObj---this指針. 服務器端的無狀態性對于網站應用而言是必要的, 但是對于復雜的企業應用而言并不是合適的約束.
      5. 對整個互聯網應用而言,URI應該是不透明的,它的結構對互聯網中間應用而言應該是不暴露的. 資源的結構是與整個互聯網架構無關的. 最近業內鼓吹REST的時候往往也推崇所謂beautify的url, 例如 http://www.my.com/blog/3/comment/1. 這種結構不過是維護url穩定性的一種副產品, 在我看來, 它對于REST而言并不是必需的. 不過根據這些年關系數據庫應用積累的經驗,識別集合和集合中的個體是一種非常通用的場景,因此我們可能規范化這種結構,甚至搜索引擎等外部組件也可能理解這種語義,從而實現更加復雜的語義網絡。在現有的所謂支持REST的web框架中, 往往支持這種規范化的url直接映射到后臺的響應函數上. https://cetia4.dev.java.net/files/documents/5545/38989/cetia4_tutorial.pdf. 例如在cetia4框架中, GET /blog/3將會被映射到后臺函數 String render(RenderContext context, int id)函數上. 在witrix平臺中, 缺省并不采用beautify的url, 但是因為對于語法成分具有明確的定義, objectEvent=ViewDetail&id=3這樣的url將映射到后臺biz-flow中的action段.
     <action id="ViewDetail-default">
      <source>
        在這里直接拿到entity對象,而不是id值
      </source>
     </action>
    在action中我們直接接觸到的不是id值,而是id值相對應的實體對象本身. 對于objectEvent=Remove, 我們可能一次刪除多條記錄, 則在后臺bizflow中action=Remove-default段將會被調用多次,每次處理一個實體. 這些自動處理機制都離不開對于標準化url組分的明確理解.
       在網站應用中, 我們一般也通過url rewrite機制來支持簡化的層級url. 但是這種根據位置來確定語義成分的url格式其實也存在著很大的局限性, 在cetia4的映射中很多時候都會出現含混的情況. 而且因為資源是抽象的, 頁面中的相對路徑計算會出現一定的困難. 在witrix平臺中, 通過tpl模板語言的標簽增強機制, 我們重新定義了頁面中的相對路徑計算規則, 從而大大簡化了資源管理問題. 在tpl中相對路徑計算永遠是基于當前模板文件的, 例如對于通過<c:include src="subdir/included.tpl" />引入的子頁面included.tpl, 在其中的<script src="included.js" />等使用相對路徑的語句會在編譯期被轉換為使用絕對路徑, 生成<script src="/contextPath/root/subdir/included.js" >等語句.
      6. 一旦url格式被規范化, 我們就可以基于它在應用程序中發展很多全局結構. 例如在cetia4中, 可以建立全局的navigation模型, 并提供了一個breadcrumb 導航欄. 這是一種全局的鏈接管理機制,在一定程度上實現了導航信息壓縮.  但是因為其沒有對象結構支撐, 與Witrix平臺的PageFlow技術相比, cetia4的方式不過是非常原始的一級策略, 它對于對象生命周期的管理也是過于簡陋的.http://canonical.javaeye.com/blog/32552
      7. REST中強調generic interface 而不是強調custom interface. 實際上目前業內的對象化方案很多時候都沉迷于提供特定結構的構造方法, 很多面向對象框架本身就在構造各式各樣的特定結構。一種通用的結構只存在于概念中,是復雜結構背后的事情。但是在很多情況下, generic interface無論在實現成本還是概念成本上都是更加低廉的. 在witrix平臺中, jsplet框架所實現的對象化就是一種generic方式的,弱類型化的, 而不是強類型的對象結構的。
      8. 關于REST的另一個有趣的問題是如果大量使用HTTP內置特性,是否我們的應用將嚴格綁定到http協議上,不再是所謂的protocol independence。不過我們真的需要同一語義模型的不同實現嗎.

    posted @ 2007-07-08 22:06 canonical 閱讀(1868) | 評論 (3)編輯 收藏

        今天adun給我講了一個他所謂可退化的設計,在我看來問題還是多多。從直觀的角度上說,在java中聲明一個具有多個參數的函數,調用的時候對于不需要用到的參數都傳入null, 這不是理想的可退化場景。所謂的退化不僅僅是概念層面的,不僅僅是關于語義的,很大程度上它也是形式上的,是關于語法結構的。
        理想的退化場景是盡量維持形式/結構穩定性的情況下實現詮釋范圍的縮減,在任何層面上都不需要知道超出當前需要的信息。而如果我們被要求必須傳入自己實際上不需要使用的參數,則必然存在著一定程度上的信息泄漏。一個樸素的看法應該是,當我們需要它是一個參數的時候它就是一個參數,當我們需要它是三個參數的時候它就是三個參數。對于系統形式結構的有效規劃是實現可退化性的前提條件。


    posted @ 2007-06-27 22:54 canonical 閱讀(917) | 評論 (3)編輯 收藏

        描述所關注的是“what”,而運行所關注的是“how”。在現代軟件開發中,描述信息作占的比重日益加大。甚至一種極端的傾向是把所有業務邏輯都寫在各種格式的配置文件中. 配置文件目前多采用xml格式,它的優點是自說明的:屬性名直接標示了其基本含義,但是這也在一定程度上加重了命名的負擔, 造成了配置文件的臃腫。因為在普通的程序語言中,可以用來傳遞信息的結構更加豐富,例如參數的相對位置,參數類型, 匿名函數, 指針引用等。而一般配置文件中沒有定義合適的繼承,封裝等抽象機制,很難如同普通程序語言那樣進行有效的結構壓縮。
        在很多靈活的弱類型語言中,借助各式語法糖(syntax sugar)可以實現描述性的運行結構, 或者可以看作是構造性的描述, 它在部分程度上消解了描述的詮釋問題, 不需要額外的解釋器即可實現描述結構的解析. 這有些類似于編譯理論中的語法制導翻譯, 在動態結構組裝方面具有明顯的優勢. http://m.tkk7.com/canonical/articles/19697.html. 但是獨立的描述信息仍然是有著重要作用的, 關鍵是作為元數據存在的描述信息可以以多種方式被使用, 并可以被部分使用. 此外一些特殊設計的描述文件可以很自然的匯集系統各個方面的信息到同一層面加以展示,而一個通用語言無論語法如何靈活, 抽象能力如何強大, 畢竟受限于先天的結構, 要做到這一點還是不現實的.
        在witrix平臺中配置文件的設計一般是綜合考慮靜態描述和動態調整的需要, 在設計上分成靜態描述段和動態運行的init段, 系統將確保init段中的tpl代碼會在適當的時候被調用.


    posted @ 2007-05-27 18:48 canonical 閱讀(1249) | 評論 (1)編輯 收藏

       在商業產品開發中,如何有效的控制同一產品的多個衍生版本是一個非常重要的問題。客戶的需求是多樣化,差異化的。這些差異有些很小,可以通過參數配置,資源裝載,skin切換等方式加以吸收,而有些則要求對界面布局和程序邏輯等作出較大調整。Witrix開發平臺在系統基礎架構方面為程序的客戶化提供了有力的支持。
       1. 多版本控制的關鍵首先在于系統良好的模塊劃分。因此Witrix平臺的beans,auth-map(權限歸約規則)等配置文件格式都支持import/include等基礎的分解策略,字符串資源和錯誤碼映射等支持多重定義文件,而對于sql.xml(外部sql語句定義), meta.xml, biz.xml, hbm.xml等配置文件采用分模塊動態裝載機制。
       2. 在Witrix系統中定義了一個特殊的custom目錄,規定了一般性的覆蓋規則:custom目錄作為系統根目錄的影子目錄,如果custom目錄下存在同名文件,則優先裝載custom目錄下的文件。例如,如果custom目錄下存在/_config/my/my.biz.xml文件,同時在根目錄下也存在/_config/my/my.biz.xml文件, 則實際裝載的是custom目錄下的實現。這里的一個關鍵在于只有meta.xml(元數據),biz.xml(BizFlow描述文件),.lib.xml(tpl模板庫)等具有一定完整性的文件才支持custom機制,而并不是所有資源都采用custom機制。如果每一個tpl文件,css文件,js文件等都優先從custom目錄下裝載,則很快就會出現循環引用,相對路徑計算將會變得非常混亂,更重要的是我們將無法定義資源刪除語義。
       3. 元數據文件,BizFlow描述文件,PageFlow描述文件等都支持復雜的extends機制,使得我們在擴展時只需要對于系統差異部分進行描述,而不是大段拷貝代碼。
       4. tpl模板庫和sql-map機制等采用的是追加覆蓋策略。例如custom目錄下的ui.xml標簽庫文件并不是直接覆蓋系統根目錄下的ui.xml文件,而是按照標簽名進行細粒度的覆蓋。系統編譯時會自動檢查覆蓋標簽的所有參數要求和原標簽相兼容(例如允許增加參數而不允許減少參數),確保所有引用到原標簽的tpl代碼仍然有效。實際上整個witrix平臺多版本擴展機制的一個設計目標就是確保平臺主系統向各個分支產品的單向信息流動。在具體的表現上就是我們隨時可以拷貝平臺主系統覆蓋到分支產品的相應目錄,所有擴展實現與主系統實現保持分離狀態。當然為了保持設計的彈性,系統中也定義了開關參數用來有選擇的跳過一致性檢查。
     

    posted @ 2007-04-22 23:15 canonical 閱讀(1525) | 評論 (4)編輯 收藏

        命名(Naming)無疑是人們認識世界最基本的手段之一。從軟件技術的發展中我們也可以觀察到命名技術的不斷深化。
        1. 助記的名:匯編之中我們有了move/push/pop這樣的指令,所面對的不再是010101這樣的同質的數字世界。變量也逐漸可以擁有自己的名字,甚至多個名字。在C語言中指針的概念被進一步抽象化,使得我們可以為任意內存地址起一個可讀的名字。我們甚至漸漸忘懷了pStruct是指針的名字,而直接把它等同于指針所指的內容本身。
        2. 局部的名:函數(例程)概念的出現把局部名稱引入系統,從此精細結構的發展才成為可能。
        3. 多義的名:面向對象的出現可以看作是命名技術的一種重大進展,它可以把一組相關的數據和函數放在一起起個名字。繼承概念為名引入了多義性。通過虛擬函數表所實現的lazy-binding部分松動了對象的名和實之間的指稱關系。現在一些所謂dynamic dispatch技術,依然是頑強的希望在同一名下,納入更多實的變化。
        4. 特指的名:面向對象技術創造一個特殊的名---this指針。它是一種約定了的固化了的局部名稱。使用this指針使得我們區分了領域(domain)的內外。在domain外對象可以有各種稱謂,而domain內我們直接通過this直接觸及到對象的實體。在javascript這樣的動態語言中,函數和this指針是動態綁定的。在某種意義上,這意味著一個操作所依賴的domain知識可以是動態變化的。
        5. 相對的名:面向對象技術所創造的知識相對化概念的一個直接體現是命名的相對化。一個函數它的具體含義不再是絕對的,而是相對于this指針的。因此我們不再采用user_load, book_load這樣的全稱的函數名, 而只定義load這樣的具有依賴性的函數。在面向對象的理想操作圖景下,首先應該是通過一個整體的參數直接區分出多個大的情景,然后在每個特定的情景下分別調用相對函數進行操作。在模板(template)技術或者動態語言中,這種相對性可以得到更加充分的發揮。因為在泛型或者弱類型語言中,我們需要的只是對象提供特定名稱的函數或屬性而已。
        6. 持久的名:在早期的語言中,名只在編譯時刻存在。在編譯出的二進制代碼中,名所提供的豐富的描述空間不復存在,我們所有的只是同質性的二機制地址而已。而在現代語言中,反射已經成為了不可或缺的技術,它使得我們在運行時刻仍然可以擁有復雜的描述結構。
        7. 分離的名:在一般的程序中,我們早已習慣了變量名直接指代實際可操作的對象本身,名的問題顯得太平庸以至于大家似乎忽略了它的存在。但是在web體系架構下, 因為存在著瀏覽器和服務器這樣兩分的狀態空間, 名成為兩個系統交互的直接手段,名的重要性也重新凸顯出來。只有在一個封閉的container中,才能通過名字解耦. 因此web架構設計的一個核心問題是構建出各種各樣的全局的container. 瀏覽器前端技術的一個本質性困難即在于多個瀏覽器窗口之間沒有共享的全局對象空間,因而很難在前臺獨立建立container結構。
       在witrix平臺的jsplet框架中,在前臺我們通過如下url來訪問后臺
      /view.jsp?objectName=MyObj&$bizId=test&objectEvent=ViewDetail&id=1
    MyObj這一參數標定了BeanContainer中的一個Java對象, $bizId參數指定應用某個Aspect到此對象上,objectEvent參數映射到WebAction上的一個java方法,而EntityManager最后負責把id映射到具體的實體對象。當我們在后臺需要編制代碼的時候,entity對象已在手邊。
        8. 名的結構:當名越來越多的時候,我們需要對它們進行有序的組織。名字空間(namespace)所采用的樹形結構可以說是最直接的一種組織方式。這一結構不僅僅可以用于描述,同時可以用于控制。

    posted @ 2007-04-01 21:30 canonical 閱讀(1466) | 評論 (3)編輯 收藏

    ??? 軟件這個領域中傳統上占優勢的是自vonNeumann以降的數學視角,計算問題是其思想內核,而函數式語言無疑是其比較貼切的表現。但是僅有數學,我們對于世界的認識是不充分的。有這樣一個笑話。燒一壺水的完整步驟如下:1.向空壺中注滿水 2.放到火爐上 3.燒到冒泡。現在有半壺水,求解燒水的步驟。數學家的回答是直接把半壺水倒掉,然后宣稱問題已經解決,因為它已經被歸結為第一個問題。實際上數學的視角直接限制了某些命題進入研究者的領域。現在業界占主流的面向對象技術,并不像是理論界的自然創造,它的思想來源更像是來自于開發窗口系統的工程實踐。http://gagne.homedns.org/~tgagne/contrib/EarlyHistoryST.html.
    ??? 面向對象技術的核心是描述問題,它試圖實現業務概念和業務關系在程序中的直接表達,所謂更貼近人的思維方式。但是從面向對象的實際操作過程我們即可得知,這里所謂的貼近只是貼近人們的常識而已。常識是有意義的,但也是淺薄的。當程序功能變得愈加復雜,程序的結構不再那么直觀的時候,我們從面向對象理論得到的支持并不如最初它宣稱的那樣的巨大。早期面向對象技術所提出的枚舉系統中所有名詞和動詞的設計方法現在看起來無疑是非常的幼稚。如何確定一個系統中到底需要定義多少個對象,以及如何確定它們之間錯綜復雜的交互關系,這些并不是通過我們的業務常識能夠確定的。
    ??? 在具體的,特定的常識與抽象的數學之間,存在著所謂的物理學。常識總是和一定的“有意義”的場景綁定著,可以直觀的理解。而數學則蒸餾出一些純粹的符號,試圖與所有預置的意義劃清界線。物理學是折衷主義的,或者說是非常狡詐的。它選擇了只在需要的時候詮釋。在物理學的推導中,大量的中間過程都是數學性的,難以尋找到明確的物理含義的,但是我們無視它,只對某個最終結論加以解釋。事實就是公式千千萬,但是我們卻只對其中的某些說:嗯,這里面有物理。與此對應,在軟件開發中,將直觀的業務需求映射到通用的程序語言實現時并不是那么直接的,在這之間可以存在著超過一般人想象的與特定業務無關的厚重的技術層。在這個層面中可以定義出非常復雜的交互模式,并在不同的特定場景下將其詮釋為不同的業務應用。這也正是平臺技術賴以生存的基礎。
    ??? 豐富的物理學的根基在于豐富的物質結構,它的核心是動力學。實際上單量子體系并不如想象中那樣難以研究,這個領域充斥著粗魯的線性近似,而它們的預測精度卻都難以想象的高。真正的復雜性來自于簡單元素所構成的復合結構,以及這些結構之間的相互作用。隨著ROR這樣的動態語言框架的流行,很多人把它們的成功歸結為語言特性的增強,這在我看來并不是富有成果的方向。誠然,更多的語法糖(syntax sugar),更多的動態性可以降低我們構建某些復雜結構的代價,但是這種降低最多是減少一兩倍代碼錄入量,而絕不可能是數量級上的影響。對于程序開發可以起到決定性作用的是那些復雜的大范圍結構,而不是通用語言本身所提供的那些抽象的簡單的局部結構本身。當然,一般人大概很少有能力做出超過一定難度的創造,一般都只是依賴現有的語言,現有的框架以直白的方式實現功能,因此很難想象可以在語法特征更少的java中輕易實現超過ROR的開發便捷性。
    ??? 通用語言的發展必然是有極限的, 也必然是貧瘠的, 因為它無法利用有限場景下的信息. 而DSL(Domain Specific Language)將注意力集中在某個特定的領域(domain)中,便可以名正言順的引入非常復雜的語法結構. 這些結構旨在本領域中具有意義,而不用擔心超出應用范圍后遭到"冗余設計"的詬病. 我無法想像在一種通用程序語言中會規定Witrix平臺中BizFlow這樣的結構設計,但是作為一種domain相關的語言結構,它的表述卻無疑是非常高效的。我相信,隨著我們對于程序結構的認識的不斷深化, 在DSL所構建的復雜結構空間中可以發展出一些真正有趣的技術.
    ??? 對于DSL存在著兩個常見的誤解.一是DSL是存在于特定領域的,因此它是一種受限制的語言,應該在計算能力上弱于圖靈機.但其實DSL的核心在于高效的表達,在于直接存在的高階結構,與它的形式計算能力并無關系.正如物理中Lagrange表述和Hamilton表述在數學上是等價的一樣,我們的選擇只在于某種情況下某種描述方式會更加方便。這里所玩的游戲更像是概念空間中的拓撲變換。
    ??? 關于DSL的另一個誤解是DSL的表述形式應該接近自然語言.但事實上數學符號和化學公式都是高效的DSL,它們的表達形式甚至內在邏輯都和我們的自然語言相去甚遠.我們是否已經完全解決了程序問題,而只是要把這種能力向無知的客戶轉授?目前在程序編碼的過程中我們仍然面臨著大量未決的問題,程序員應該是DSL的直接受益者.此外,西人對于語言的認知是偏狹的,因為他們眼中的language只有拉丁語系和日耳曼語系,而不知道這個世界上還存在著不符合西文語法的漢語。按照朱光潛的詩論,西人長時間認為詩是不宜于寫景狀物的,因為語言是串行的,因而只適于按照步驟敘事,卻不了解漢語的自由組合形式和豐富的單字表現力可以輕易捕獲微妙的瞬間.

    posted @ 2007-03-18 23:05 canonical 閱讀(1653) | 評論 (0)編輯 收藏

    ?? 最近D語言發布了1.0版,這是一個由編譯器開發者所設計的編譯語言,語法類似C++, 但是針對C++的弊病作了大量修正,并增加了很多現代特征,其中還是有一些新意在其中的。http://www.digitalmars.com/d/overview.html 我對其比較感興趣的部分是D語言明確提出的編譯期運行的概念。雖然C++讓大眾了解了meta programming技術,很多人因此認為meta programming的威力在于類型演算,但是在我看來meta programming的真正作用在于在編譯期可以“動態”產生或調整代碼結構。它依賴于類型是因為我們只能利用類型來承載一些額外信息, 這無疑也是對于類型的一種濫用。在D語言中template所接受的不僅僅是類型, 或者類型的類型,它可以是任何符號.
    ? template MixInAttr(T, char[] name){?
    ???? mixin(" T _" ~ name ~";");
    ???? mixin(" T "~name~"(){ return _"~name~"; }");
    ???? mixin(" void "~name~"(T v){ _"~name~" = v;}");
    ? }?
    ?
    ? template MixInOtherAttr(T, T v){
    ??? T _otherAttr = v;
    ???
    ??? int otherAttr(){ return _otherAttr; }
    ? }
    ?
    ? const int myValue = 1;
    ?
    ? int addFunc(int x){
    ??? return x + 1;
    ? }
    ??
    ? class MyTest{?
    ???? mixin MixInAttr!(int, "myAttr");?
    ???? mixin MixInOtherAttr!(int,4);
    ????
    ???? static if(addFunc(myValue) 〉 0){
    ??????? int testFunc(){ return 5;}
    ???? }
    ? }
    ?
    ? void main(){?
    ???? auto t = new MyTest;
    ???? t.myAttr = 3;
    ???? int v = t.myAttr;???
    ???? v = t.otherAttr;
    ???? t.testFunc();
    ? }??
    ? 不過現在編譯期運行無疑是一個正在探索的方向, 在D語言中的使用方式并不是非常理想的, 在形式和功能實現上都存在著重大改進的可能.?
    ?
    ? 在witrix平臺的tpl模板語言中,我們也引入了編譯期運行的概念,只是tpl的語言特征非常簡單再加上xml格式特殊的規范性,編譯期運行在tpl中的實現是非常直接和明確的.在tpl中定義了<cp:run〉標簽,它的內容在編譯期運行, 輸出結果(xml字符串)將被繼續編譯. 在<cp:run〉中可以執行任何有效的tpl代碼, 它們在編譯期狀態空間中運行. 例如
    ?〈cp:run〉
    ?? 〈c:forEach var="_x" items="${tagBody.children()}"〉
    ?????? bla bla bla...
    ?? 〈/c:forEach〉
    ?〈/cp:run〉
    在EL表達式中我們通過cp前綴實現普通調用和編譯期調用的混雜.
    ? 〈cp:const class="mypkg.MyConstantClass"/〉
    ? 〈c:eval expr="${myFunc(cp:const.MY_CONST, commonVar, cp:funcInCompileTime())}" /〉
    ? 〈cp:compile test="${exprInCompileTime}"〉
    ???? any tpl ...
    ? 〈/cp:compile〉

    ?其實當我們把改進的目光開始放到編譯期的結構方面的時候, 可以做的工作是非常多的. 例如從結構上看, 繼承策略相當是類結構的一種一階替換策略.
    ? 類B(methodB) extends 類A(methodA, methodB)? ==〉 類B(methodA[inA], methodB[inB])
    如果我們放棄概念層面上的糾纏,而如同template那樣只關注語法結構, 則可以發展出更加復雜的替換操作.
    ? NODE_B(?????????????????????????? NODE_A(????????????????????????????????? NODE_B(
    ??? SUB_NODE_A1???????〉〉??? SUB_NODE_A1???????????? ==〉??? SUB_NODE_A1
    ????? SUB_NODE_B11????????????????? SUB_NODE_A11?????????????????????????? SUB_NODE_B11
    ???????????????????????????????????????????????????? SUB_NODE_A12??????????????????????????SUB_NODE_A12
    ? )????????????????????????????????????????? )?????????????????????????????????????????????????????? )
    C++中及D語言中的template技術在某種意義上相當于是在代碼結構中預留了空洞, 可以實現跨越類結構的替換填充. 只是D語言挖洞的能力無疑比C++強大的多.?
    ? 如果我們考察的再細致一些, 就會發現兩個語法節點的融合也是存在多種策略的.
    ? B 〉〉 A ==〉 (remove_A, replace_A, insert_B_before_A, insert_B_after_A, insert_B_into_A, insert_A_into_B)
    而通過insert_A_into_B/insert_B_into_A策略既可實現所謂的AOP intercept操作. http://canonical.javaeye.com/blog/34941?在witrix平臺的BizFlow技術中, 我們通過高級的結構融合策略實現為任意實體引入流程支持. 最簡單的情況下我們所需要做的工作只是增加一個語法元素
    ?〈bizflow extends="myflow"〉
    引入流程意味著對界面的一系列修正, 例如增加,刪除某些菜單, 同時要增加很多流程相關函數, 對某些函數實施AOP操作, 在各處引入權限控制等等, 這些都可以通過extends操作引入.

    ? 在傳統上, 編譯器結構是固化的, 它所編譯的代碼結構是固化的, 而它所編譯出的代碼也是固化的, 但是現代語言的各種發展正致力于在各個層面引入動態性. 編譯期運行抑或是編譯期結構操縱技術的引入是在一個層面上打開了潘多拉魔盒. 它讓我們看到了前所未有的技術可能性, 但它無疑也是危險的,難以控制的. 我們目前的做法是盡量克制,只在局部使用, 但我相信它在很多語言中都是可以在理論上嚴格定義,并精確實現的, 我們最終也能夠找到合適的形式來約束它的破壞性. 在這個過程中我們需要引入更多的物理化的視角。

    posted @ 2007-03-04 18:14 canonical 閱讀(1654) | 評論 (0)編輯 收藏

    僅列出標題
    共18頁: First 上一頁 2 3 4 5 6 7 8 9 10 下一頁 Last 
    主站蜘蛛池模板: 最新国产成人亚洲精品影院| 免费看黄网站在线看| 永久免费bbbbbb视频| 美女被爆羞羞网站免费| 亚洲热妇无码AV在线播放| 最近中文字幕免费2019| 欧美亚洲国产SUV| 激情综合色五月丁香六月亚洲| 中文字幕免费在线看线人| 色天使亚洲综合一区二区| 亚洲va久久久噜噜噜久久天堂| 日韩精品成人无码专区免费 | 亚洲国产美女福利直播秀一区二区| 免费黄色毛片视频| 成在线人视频免费视频| 亚洲狠狠成人综合网| 亚洲日韩精品无码专区网址| 成人黄页网站免费观看大全| 精品一区二区三区免费观看| 亚洲久悠悠色悠在线播放| 亚洲精品午夜国产VA久久成人| 女性无套免费网站在线看| 成全高清在线观看免费| 亚洲中文无码mv| 亚洲bt加勒比一区二区| 亚洲VA综合VA国产产VA中| 国产麻豆视频免费观看| 嫩草影院在线播放www免费观看| 亚洲av无码一区二区三区天堂| 亚洲av日韩av无码黑人| 亚洲国产aⅴ综合网| 在线观看人成视频免费| 99re在线这里只有精品免费| jizz在线免费观看| 亚洲av中文无码乱人伦在线观看 | 亚洲六月丁香六月婷婷色伊人| 中文字幕中韩乱码亚洲大片| 在线看片无码永久免费aⅴ| 18观看免费永久视频| 波多野结衣免费一区视频 | 国产免费看插插插视频|