腳本的未來
1. 編程模型的比較
下面是一些關于多態、靈活性的簡單例子。假設我們有如下類型定義。
class Dog {
run();
};
class Car {
run();
};
class Chair{
stand();
};
dog, car, chair 分別是這些類型的實例 instance.
我們有個公用函數。
makeItRun( param){
param.run();
}
分別調用這些實例的Run方法
A. 解釋腳本,如JavaScript, Python, Ruby, FP
makeItRun( dog); // OK
makeItRun( car); // Ok
makeItRun( chair); // Runtime Error
特點: 根據符號、名字進行綁定, 運行期松耦合. 相當于語法直接支持Reflection。
B. 虛擬機編譯語言,如 Java, C#
makeItRun(param){
param.run();
}
makeItRun( dog); // Compilation Error
makeItRun( car); // Compilation Error
makeItRun( chair); // Compilation Error
我們必須 讓Dog 和 Car 實現相同的接口比如Runnable.
interface Runnable{
run();
}
并且這么定義
makeItRun(Runnable param){
param.run();
}
這樣.
makeItRun( dog); // Ok
makeItRun( car); // Ok
makeItRun( chair); // Compilation Error
特點: 根據類型契約綁定. 編譯期類型檢查
C. Reflection API
我們可以使用 Reflection API 達到類似于解釋腳本的效果.
makeItRun(Object param){
methodInvoke(param, “run”);
}
makeItRun( dog); // Ok
makeItRun( car); // Ok
makeItRun( chair); // Runtime Error
特點: 語法本身不支持名稱符號綁定,需要使用Reflection API, 這些API由Class 結構元數據支持.
D. C++ Template
<class T>
makeItRun(T param){
param.run();
}
makeItRun( dog); // Ok
makeItRun( car); // Ok
makeItRun( chair); // Compilation Error
特點: 編譯期名稱、符號綁定. Very cool.
注意: Java范型不支持這種方式。Java范型進行編譯期類型檢查。也是類型綁定的。C++ Template并不是真正的范型編程,只是一種代碼生成機制。
總結:
運行期名稱符號綁定,并不適合大規模復雜系統開發,因為沒有編譯期類型檢查,不支持Java Interface那樣的契約編程。
至于Ruby on Rails, 很像一個簡單的代碼生成器.
對于大型系統,比起運行期名字綁定,C++ Template 的編譯期綁定也許更適合,至少有編譯期檢查。
解釋腳本最適合哪些領域?
解釋腳本是運行期名稱綁定,松耦合。
什么系統需要這樣的特性?
對了. SOA, Web Services, such buzzwords – 定位服務名稱,調用注冊的對象方法.
2. 腳本的可能未來
(1) 服務器段流程控制
JavaScript, Ruby, Python, FP 支持Continuation. 有時用作狀態機流程控制。
Continuation 甚至比狀態機. 可以跳到運行棧的任何一層。 (類似于Exception Throw/Handling).
個人觀點,并不欣賞這種使用方法。因為web-based services應該設計為盡量無狀態的。狀態應該盡量保持在客戶端,比如AJAX/Flex. 有人說,如果有人刷新了URL,客戶端保存的所有的中間狀態都會丟失,最好服務器段記錄所有的中間狀態,這樣用戶下次可以回到上次的斷點。對于 long-session 的應用,這是對的. 但是對于long-session 的應用來說,為了均衡負載,系統更應該被設計為無狀態的。所以,使用腳本的Continuation特性,仍然沒有太大的意義。
(2) Web Service 客戶端
AJAX/Flex 也可以看作Web Service 客戶端.
腳本調用Web Service,我欣賞這種用法。用腳本表達Web服務調用非常方便清楚,不需要Reflection API 和 Code 生成。
(3) 把Mobile Code 從 客戶端遷移到 服務端
假設我們有如下的Web Service客戶端腳本,
If(service.do() == ok) {
nextService.do();
nextService2.do();
}else{
backService.do();
backService2.do();
}
這通常意味著要訪問三次Web Service Server. 每一次需要組裝一次SOAP 或者XML-RPC 消息.
把整個Script一次發送過去如何?
服務器解釋整個腳本,一次執行所有的服務請求,一次返回最終結果。
這涉及到安全問題。幸好腳本比機器碼或者VM指令更容易管理和控制,解決這個問題應該不難。
(4) DSL, LOP ?
Domain Specific Languages 如Business Rule, Workflow Definition 要求用戶友好,更加像英語,而不是編程語言。
普通用戶喜歡 關鍵字,而不是 API。
If a greater-than b then do … // keywords way
If(greater(a, b)) { … // API way
腳本是更高級的語言,通常比編譯語言更加友好。一些腳本(如 Lisp, Scheme, etc)可以定義更多的關鍵字。