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

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

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

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

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

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

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

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

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

              今天adun給我講了一個他所謂可退化的設(shè)計,在我看來問題還是多多。從直觀的角度上說,在java中聲明一個具有多個參數(shù)的函數(shù),調(diào)用的時候?qū)τ诓恍枰玫降膮?shù)都傳入null, 這不是理想的可退化場景。所謂的退化不僅僅是概念層面的,不僅僅是關(guān)于語義的,很大程度上它也是形式上的,是關(guān)于語法結(jié)構(gòu)的。
              理想的退化場景是盡量維持形式/結(jié)構(gòu)穩(wěn)定性的情況下實現(xiàn)詮釋范圍的縮減,在任何層面上都不需要知道超出當(dāng)前需要的信息。而如果我們被要求必須傳入自己實際上不需要使用的參數(shù),則必然存在著一定程度上的信息泄漏。一個樸素的看法應(yīng)該是,當(dāng)我們需要它是一個參數(shù)的時候它就是一個參數(shù),當(dāng)我們需要它是三個參數(shù)的時候它就是三個參數(shù)。對于系統(tǒng)形式結(jié)構(gòu)的有效規(guī)劃是實現(xiàn)可退化性的前提條件。


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

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


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

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

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

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

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

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

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

          ?? 最近D語言發(fā)布了1.0版,這是一個由編譯器開發(fā)者所設(shè)計的編譯語言,語法類似C++, 但是針對C++的弊病作了大量修正,并增加了很多現(xiàn)代特征,其中還是有一些新意在其中的。http://www.digitalmars.com/d/overview.html 我對其比較感興趣的部分是D語言明確提出的編譯期運行的概念。雖然C++讓大眾了解了meta programming技術(shù),很多人因此認為meta programming的威力在于類型演算,但是在我看來meta programming的真正作用在于在編譯期可以“動態(tài)”產(chǎn)生或調(diào)整代碼結(jié)構(gòu)。它依賴于類型是因為我們只能利用類型來承載一些額外信息, 這無疑也是對于類型的一種濫用。在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();
          ? }??
          ? 不過現(xiàn)在編譯期運行無疑是一個正在探索的方向, 在D語言中的使用方式并不是非常理想的, 在形式和功能實現(xiàn)上都存在著重大改進的可能.?
          ?
          ? 在witrix平臺的tpl模板語言中,我們也引入了編譯期運行的概念,只是tpl的語言特征非常簡單再加上xml格式特殊的規(guī)范性,編譯期運行在tpl中的實現(xiàn)是非常直接和明確的.在tpl中定義了<cp:run〉標簽,它的內(nèi)容在編譯期運行, 輸出結(jié)果(xml字符串)將被繼續(xù)編譯. 在<cp:run〉中可以執(zhí)行任何有效的tpl代碼, 它們在編譯期狀態(tài)空間中運行. 例如
          ?〈cp:run〉
          ?? 〈c:forEach var="_x" items="${tagBody.children()}"〉
          ?????? bla bla bla...
          ?? 〈/c:forEach〉
          ?〈/cp:run〉
          在EL表達式中我們通過cp前綴實現(xiàn)普通調(diào)用和編譯期調(diào)用的混雜.
          ? 〈cp:const class="mypkg.MyConstantClass"/〉
          ? 〈c:eval expr="${myFunc(cp:const.MY_CONST, commonVar, cp:funcInCompileTime())}" /〉
          ? 〈cp:compile test="${exprInCompileTime}"〉
          ???? any tpl ...
          ? 〈/cp:compile〉

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

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

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

          僅列出標題
          共18頁: First 上一頁 2 3 4 5 6 7 8 9 10 下一頁 Last 
          主站蜘蛛池模板: 油尖旺区| 射阳县| 柯坪县| 淳化县| 临泉县| 乌兰县| 汶上县| 凌海市| 陇川县| 洪湖市| 新乐市| 资阳市| 潼关县| 财经| 大丰市| 东兰县| 石河子市| 勃利县| 平果县| 秦皇岛市| 松阳县| 瑞金市| 芜湖县| 潜山县| 莆田市| 抚远县| 贡觉县| 澄江县| 天津市| 三原县| 奉贤区| 嘉黎县| 高碑店市| 北碚区| 鄯善县| 栖霞市| 辛集市| 冷水江市| 保靖县| 崇州市| 黔西|