很長時間以來我對rails框架本身沒什么興趣,因為我從來都不是web fans,15歲那年我打印了一本HTML Reference準備學習一下,感覺完全nonsense。很長一段時間(大約有3年吧)里基本上看到Markup Language我就會大腦短路。但是我對rails背后的東西很感興趣,是什么讓rails如此有效率,一開始我以為是Ruby DSL,但隨著做的rails項目越來越多,我發現rails的效率的根源來自它對delphi的繼承和發揚。

1.? data centric object model Active Record
delphi之所以成功,在于它看準了大部分商用軟件都是數據庫核心的,并為之設計一套相應的框架, delphi的核心就是圍繞數據庫進行開發(李維同學的borland傳奇里寫道,當時之所以起名字叫Delphi,就是因為要taking to Oracle)。而rails也很好的在新時代(Web時代)把握了相似的核心點——content是web的核心,以及數據庫數據到content的映射是動態web的核心。因此它沒有采用所謂的更加嚴肅的ORM技術。而是依然使用了delphi時代的active record(但是進行了object封裝)。如下代碼示范了ruby和delphi在active record實現上的相似

Ruby
class?Person?<?ActiveRecord::Base
end

x8x?
=?Person.new?:name?=>?'x8x'
x8x.age?
=?15

Delphi

people?:?TADOTable;

begin???
???people.Table?
=?'people';
???people.InsertRecord(
'x8x');

???people.First;
???people.FieldByName(
'age')?:=?15;
end


可以看出,Delphi的數據庫味道更濃一些,而ruby則更多使用了對象的視角(我記得在98年前后(我變成oo狂熱分子之后),在寫delphi的時候我基本上不會直接使用Table對象了,而是做一些簡單的封裝,用business object代替直接的數據庫對象。但是最后由于和delphi的ui組件結合的不好而放棄)。但是active record的pattern是一致的。

2. DB(resource)-aware UI component —— Action View

Delphi另一個為人稱道的地方是DB-Aware的UI組件,像TDBLabel, TDBMemo還有至今仍位人稱道的TDBGrid,極大的簡化了UI的開發。不過說到底,仍然是Delphi數據庫核心策略的延續。同樣,rails的view helper也是db核心的。text_field之類的可以自動感知active record的內容和錯誤。

<label>Name:</label>?<%=?text_field?'person',?'name'?%>



nameLabel?:?TDBLabel;

nameLabel.DataSource?
=?peopleTable;
nameLabel.Field?
=?'name';
nameLabel.Label?
=?'Name';

拋開Desktop和web的差異,也可以算是大致相當吧。

3. Simple Component Model —— Plan Object as Component

Delphi是基于組件開發,并且是非常成功的一個組件模型。基本上有經驗的delphi程序員,都會在開發過程中抽象幾個VCL component出來簡化自己的開發。一方面是DRY精神,另一方面Delphi簡單的組件模型使得這樣做的代價非常的小。Delphi的組件基本上就是一個對象,重構的過程中修修改改就成組件了。rails其實有類似的機制,而且更簡單直接,更符合web時代的胃口,一個對象外加一個helper就可以成為一個UI組件。與此同時rails還有另外一個天然的同盟——Ruby DSL。把以前Delphi需要用UI設計器的地方都用Ruby DSL代替了。這一點是我最近在用rails做曹老師華麗的RedSaga的時候推行DSL geek主義時發現的。比如現在我有這樣一個tiny DSL用以定義portlet:

in controller

@portlet?=?Portlet.new?do
????????????name?
'administration'
????????????title?
'Administration'
????????????tabs?
do
????????????????Projects?:controller?
=>'projects',?:action?=>?'list'
????????????end
????????end

in view
<%=?render_portlet?@portlet?%>

這種描述/configuration block風格的dsl與delphi組件的初始化非常相似,或者可以說,只有語法上的差異而無思路上的差異(當然delphi可以借助IDE而不是語言來指定這些,但是這個做法是沒有生產力的)。

with?Portlet?do
???Label?
=?
???Name?
=?.
???Tabs[
0].Controller?=?
???Tabs[
1].Action?=?
end

rails和delphi這種輕量的組件模型,使得構建組件/復用組件級的代價極小。因此可以極大的提高開發效率(我至今仍記得,01年前后接了一個Delphi私活,客戶要求Office XP菜單風格,我找了一個XPMenu的控件,直接仍上去,自己的代碼一行沒改,菜單就Office XP了...)。

總之,Delphi的效率要素Rails大部分都學走了,最后簡單總結一下rails在delphi基礎上的發揚:

1. 用ruby而不是object pascal。語法上更靈活簡單
2. Object Model on top of ActiveRecord,比起Delphi可以跟好的使用OO開發。
3. 組件模型更簡單
4. CoC,這個就不說了
5. expressive Ruby DSL

最后最后,說一下Delphi for PHP,做得很華麗。但是UI部分我不是很喜歡。