雖然Web 2.0應用程序著實讓人興奮,但它們在下一代RIA+SOA集成平臺形成之前是不會成為主流的。
下一代RIA+SOA平臺什么樣子
目前,在基于HTML、CSS、Javascript標準的網絡環境下,RIA開發人員在構建富用戶界面時,必須對多種第三方庫文件和框架進行編譯。這種“ 照單選菜”的RIA程序開發方式給開發人員增加了多余的負擔。他們不能將精力全部用于編寫程序,而必須拿出部分時間用來尋找、集成和整理各種各樣的RIA 開發平臺。
SOA方面也是如此。開發人員必須自己解決如何創建服務,以及如何將這些服務集成到RIA前端程序。開發人員需要一個能解決編寫程序時所需考慮的各種問題的平臺,這樣他們才能把精力放在他們最擅長的事情上——編寫程序。
問題是:下一代RIA+SOA平臺應該是什么樣子呢?
我們可以從建立一個RIA+SOA應用的活動開始。一般來說,這些活動主要包括:
1、設計程序的“樣子”
也就是程序的總體外觀。它包括以下方面:顏色、字體、圖表,以及總體頁面布局。
常用工具包括:HTML、CSS和圖像工具。
2、集成控件(widget)
控件將一系列常用功能封裝在一個單獨的組件里。除一些預定義的動態行為之外,它們通常還包含“感觀”效果。它們是RIA程序的基礎組成模塊。
常用工具包括:ExtJS、Dojo、Yahoo YUI,以及一些其它小型控件工具。
3、為用戶界面添加動態行為
在用戶界面創建動態行為涉及兩件事:
事件處理
文檔對象模型(DOM)操作
事件處理是對發生的特定事件(比如用戶點擊一個按鈕或者收到服務響應)進行判定的能力。DOM操作可以讓你根據接收到的事件動態改變用戶界面。
常用工具包括:Javascript庫類,比如JQuery、Prototype和Scriptaculous。
4、使用服務
RIA的一個主要功能是使用后端服務。這使它可以用單頁面用戶界面傳輸服務的應用數據。用戶界面與服務層也可以完全分開。Ajax是最常用的與服務交互的方法。
常用工具包括:Javascript庫類,比如Jquery和Prototype。
5、創建服務
服務為數據和應用業務邏輯層提供了一個接口。
常用工具包括:可以根據你所用的程序設計語言選擇適當的框架來創建服務。
下一代RIA+SOA平臺基本特征
了解了創建RIA+SOA應用程序的大致需求,我們再來看一下怎樣將這些活動整合到一起,從而最大化開發人員的效率。下面幾個部分概述了下一代RIA+SOA平臺的基本特征。
1、支持HTML和CSS
這兩種語言非常適合用來實現應用程序的“外觀”,并且大多網絡用戶界面的開發人員對它們都很熟悉。所以沒必要再去另做一些工作實現重復的功能。
2、提供開放的控件框架(Open Widget Framework)
正如前面講到的,控件是RIA程序的基礎組成模塊。有許多工具可以使用,比如Yahoo、Dojo和ExtJS。也有一些小型項目或個人開發的獨立控件。你可以使用這些控件構建RIA程序,但有一些需要注意的地方:
幾乎不可能僅靠一個控件來滿足你所有的需求。
集成各種第三方控件時可能需要定制代碼,并對各個控件有深入的了解。
編寫新的控件是一項有挑戰性的工作,因為這意味著你得編寫自己所用的控件工具的低層API,甚至要從零開始。
某些控件框架要求開發人員為所用的控件編寫大量的JavaScript,這對那些JavaScript開發經驗很少甚至沒有的人來說,無疑是有很大問題。
為解決以上問題,RIA+SOA平臺提供的開放控件框架需要具備以下功能:
·支持集成現有的第三方控件
·為新建控件提供簡單的API
·可以通過簡單標記(markup)使用控件(不需要使用JavaScript)
·支持分布模型,以簡化新控件的提交、發現和使用。
開放的控件框架將成為開發人員獲取控件的資源,并使開發人員可以很容易地集成控件和應用程序。如果沒有所需的控件,使用開放控件框架的API重新創建也很容易。
由于控件在RIA開發中的重要性及其分散的特性,開放的控件框架應該是任何RIA+SOA平臺必不可少的組成部分。
3、提供一個集成的RIA編程模型
與傳統的Web應用相比,RIA程序需要編寫更多的用戶界面代碼。因此,下一代平臺需要集成的RIA編程模型來簡化主要用戶界面設計任務。這些任務包括:
·事件處理
·DOM操作
·服務使用(Ajax)
事件處理、DOM操作和Ajax是富網絡應用中實現“富”任務的部分。它們的關系非常緊密。為說明這一點,我們來看一個典型的RIA登錄過程。
·點擊登錄按鈕(事件處理)
·發送服務請求(Ajax)
·顯示相應的活動指示器(DOM操作)
·返回服務(Ajax)
·關閉活動指示器(DOM操作)
·顯示登錄“成功”的消息(DOM操作)
雖然它們關系緊密,大部分框架和庫都只提供了簡單的集成,而讓開發人員完成剩下的任務。為表明這一點,我們來看一些代碼。在下面的示例中,當一個組合框的值發生改變時,我們將設定另一個組合框的內容。示例是用Jquery寫的。
$(function(){$(“select#comboOne”).change(function(){$.getJSON(“/combo.php”,{id: $(this).val(), ajax: “true”}, function(j){var options = “”;for (var i = 0; i < j.length; i++) {options += “” + j[i].optionDisplay + “”;}$(“select#comboTwo”).html(options);})})})
現在我們來看看怎么用事件處理、DOM操作和Ajax完全集成的方法來完成同樣的任務。
on=“change then r:load.combo2.request”>on=“r:load.combo2.response then value[property=rows,text=text,value=value]”>
這兩段代碼用不同的方式完成同一件任務。第一段使用了較多的代碼,并且都是用JavasSript。第二段使用了簡單的表達式語言來完成同樣的任務。我們來分析一下語法。
on=“change then r:load.combo2.request”
在這句表達式中,當 on=“r:load.combo2.response then value[property=rows,text=text,value=value]
and effect[Highlight]”>
通過在表達式中添加effect[Highlight],我們就能使用一種微妙的效果來提示使用者組合框的值已經發生變化。
這些示例代碼顯示了事件處理、DOM操作和Ajax完全集成這一方法的強大與簡易。沒有JavaScript經驗的開發人員也很容易掌握像上面所示的表達式語言。這將使他們很快進入工作狀態,因為他們不再需要預先進行大量枯燥的學習。當然,有JavaScript經驗的開發人員也可以自由選擇使用 JavaScript。這樣,一個集成的RIA編程模型也應該支持JavaScript,特別是要支持行為與標記的分離。通常稱之為低調(unobtrusive)JavaScript。我們來看一個示例:
$(“progress_images”).on(“r:login.request then show”).on(“r:login.response then hide”);
在這個示例中,標記與JavaScript代碼定義的行為——收到登錄請求消息的時候“show”及收到登錄響應消息的時候“hide”——就是分離的。 這種編程模型有利于喜歡使用JavasScript進行RIA編程的開發人員。
一個集成的RIA編程模型是RIA+SOA平臺的基礎組成部分。它為開發人員處理主要的RIA編程活動提供了單一、完整的機制。這樣,相較現在來說,開發人員可以使用更少的代碼、更快地構建富用戶界面。
4. 提供集成的服務平臺(Integrated Services Platform)
RIA 只是構建富應用程序的一部分。我們仍需要完成RIA+SOA中的SOA部分。不幸的是,當前的Web 2.0工具包和框架主要用于RIA,很少甚至不提供對構建服務的支持。這確實是個問題,因為這樣又需要開發人員來完成大量的工作,使得應用開發和維護需要耗費更多的時間并變得異常困難。
下一代RIA+SOA平臺要解決這個問題必需提供一個能滿足以下條件的集成的服務平臺:
·支持使用任何語言創建服務
·實現RIA與SOA層的無縫交互
·可以使用本地模擬服務(mock service)
過去,網絡框架使用單一的編程語言構建,但是在RIA+SOA時代,這種做法將變得過時并且多余。RIA程序只與服務交換應用數據,它們應該是獨立于編程語言的。RIA程序與SOA服務只需要一個簡單的消息關系。RIA與SOA層之間的松耦合特性為集成的服務平臺提供了方法,可以使開發人員使用任何編程語言創建服務并不會影響到RIA層。
集成的服務平臺同樣應該提供RIA與SOA各層之間的無縫交互。特別是,它應該代替開發人員處理服務路由選擇和數據轉換。下面是一個用簡單的集成方法創建服務的示例。這個示例是用Java編寫的。
@Service (request = 'login.request‘, response ='login.response’)protected void loginRequest (Message req, Message resp)throws Exception{String username = req.getData().getString(“username”);String password = req.getData().getString(“password”);User user = UserDAO.login(username,password);if (user !=null){response.getData().put(“success”,true);response.getData().put(“user”,user);return;}response.getData().put(“success”,false);}
在上面的示例中,有兩點需要注意:首先,通過在Java方法中加入一個簡單的“Service”注釋便讓一個平常的Java對象變成了一個服務。注釋中包含了這個方法所處理的服務請求和服務響應消息,使路由設置變得簡單。其次,可以簡單明了地處理請求和響應數據。在這個示例中,將整個User對象放入響應消息中。服務平臺負責處理數據轉換。這樣開發人員可以集中精力編寫服務邏輯而不是膠合代碼(glue code),可以減少代碼量并提高開發速度。
然后,如果RIA與服務之間的關系是基于消息的,就可以創建本地模擬服務。本地模擬服務可以響應遠程請求,但它們只存在于本地RIA中。這是一種很強大的功能,因為無需一行服務代碼便可創建功能齊全的RIA模型。可以將這些本地模擬服務放在單個文件中,并在用戶界面開發完成后刪除。我們來看一個例子:
on=“r:login.request then show or r:login.response then hide”/>Username: Password: on=“click then r:login.request”/>登錄表單$MQ(‘r:login.response’, {'success‘:true,'username’:‘foo'});
模擬服務
在上面的示例中,我們有一個產生服務請求r:login.request的登錄表單。我們還有一張圖像,它將在收到r:login.request消息時顯示,并在收到r:login.response消息后隱藏。第二部分是一個模擬服務的示例。這個模擬服務監聽r:login.request服務請求,并在一秒后用r:login.response消息響應(當然這一秒只是模擬服務延遲)。登錄表單并不知道服務的位置,它只負責響應消息。這個簡單的示例顯示了如何不靠一行服務代碼創建一個完整的RIA模型。這種模型是100%可重用的,并使開發人員可以在服務創建之前定義服務合約。這樣,服務創建工作得到了很大程度的簡化,因為開發人員不僅有一個功能齊全的模型作為參考,還同時得到了一個完整的服務界面。
總結
開發人員目前正在經歷網絡應用開發的巨大轉變。我們正從Web 1.0的基于服務器的MVC模式轉為面向網絡的客戶機/服務器架構,或者更準確一點應該稱為RIA+SOA。由于這個轉變,開發人員要將他們所用的網絡開發平臺集成到一起才能進行富網絡應用的開發。當然,轉變的同時也會帶來機會。這個機會便是建立下一代為Web 2.0應用提供端對端支持的網絡平臺。
在 Appcelerator,我們看到公司在一年以前已經接受這種轉變。他們正在開發Appcelerator Platform,這是一個支持RIA+SOA的全新平臺。本文所用的示例正是基于這一平臺。當然,創建下一代網絡平臺有許多不同的方法。但是,即使實現細節上有些許不同,大體特征應該都是一樣的。