很長時間以來我對rails框架本身沒什么興趣,因為我從來都不是web fans,15歲那年我打印了一本HTML Reference準備學(xué)習(xí)一下,感覺完全nonsense。很長一段時間(大約有3年吧)里基本上看到Markup Language我就會大腦短路。但是我對rails背后的東西很感興趣,是什么讓rails如此有效率,一開始我以為是Ruby DSL,但隨著做的rails項目越來越多,我發(fā)現(xiàn)rails的效率的根源來自它對delphi的繼承和發(fā)揚。
1.? data centric object model Active Record
delphi之所以成功,在于它看準了大部分商用軟件都是數(shù)據(jù)庫核心的,并為之設(shè)計一套相應(yīng)的框架, delphi的核心就是圍繞數(shù)據(jù)庫進行開發(fā)(李維同學(xué)的borland傳奇里寫道,當(dāng)時之所以起名字叫Delphi,就是因為要taking to Oracle)。而rails也很好的在新時代(Web時代)把握了相似的核心點——content是web的核心,以及數(shù)據(jù)庫數(shù)據(jù)到content的映射是動態(tài)web的核心。因此它沒有采用所謂的更加嚴肅的ORM技術(shù)。而是依然使用了delphi時代的active record(但是進行了object封裝)。如下代碼示范了ruby和delphi在active record實現(xiàn)上的相似
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的數(shù)據(jù)庫味道更濃一些,而ruby則更多使用了對象的視角(我記得在98年前后(我變成oo狂熱分子之后),在寫delphi的時候我基本上不會直接使用Table對象了,而是做一些簡單的封裝,用business object代替直接的數(shù)據(jù)庫對象。但是最后由于和delphi的ui組件結(jié)合的不好而放棄)。但是active record的pattern是一致的。
2. DB(resource)-aware UI component —— Action View
Delphi另一個為人稱道的地方是DB-Aware的UI組件,像TDBLabel, TDBMemo還有至今仍位人稱道的TDBGrid,極大的簡化了UI的開發(fā)。不過說到底,仍然是Delphi數(shù)據(jù)庫核心策略的延續(xù)。同樣,rails的view helper也是db核心的。text_field之類的可以自動感知active record的內(nèi)容和錯誤。
<label>Name:</label>?<%=?text_field?'person',?'name'?%>
和
nameLabel?:?TDBLabel;
nameLabel.DataSource?=?peopleTable;
nameLabel.Field?=?'name';
nameLabel.Label?=?'Name';
拋開Desktop和web的差異,也可以算是大致相當(dāng)吧。
3. Simple Component Model —— Plan Object as Component
Delphi是基于組件開發(fā),并且是非常成功的一個組件模型。基本上有經(jīng)驗的delphi程序員,都會在開發(fā)過程中抽象幾個VCL component出來簡化自己的開發(fā)。一方面是DRY精神,另一方面Delphi簡單的組件模型使得這樣做的代價非常的小。Delphi的組件基本上就是一個對象,重構(gòu)的過程中修修改改就成組件了。rails其實有類似的機制,而且更簡單直接,更符合web時代的胃口,一個對象外加一個helper就可以成為一個UI組件。與此同時rails還有另外一個天然的同盟——Ruby DSL。把以前Delphi需要用UI設(shè)計器的地方都用Ruby DSL代替了。這一點是我最近在用rails做曹老師華麗的RedSaga的時候推行DSL geek主義時發(fā)現(xiàn)的。比如現(xiàn)在我有這樣一個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風(fēng)格的dsl與delphi組件的初始化非常相似,或者可以說,只有語法上的差異而無思路上的差異(當(dāng)然delphi可以借助IDE而不是語言來指定這些,但是這個做法是沒有生產(chǎn)力的)。
with?Portlet?do
???Label?=?
???Name?=?
.
???Tabs[0].Controller?=?
???Tabs[1].Action?=?
end rails和delphi這種輕量的組件模型,使得構(gòu)建組件/復(fù)用組件級的代價極小。因此可以極大的提高開發(fā)效率(我至今仍記得,01年前后接了一個Delphi私活,客戶要求Office XP菜單風(fēng)格,我找了一個XPMenu的控件,直接仍上去,自己的代碼一行沒改,菜單就Office XP了...)。
總之,Delphi的效率要素Rails大部分都學(xué)走了,最后簡單總結(jié)一下rails在delphi基礎(chǔ)上的發(fā)揚:
1. 用ruby而不是object pascal。語法上更靈活簡單
2. Object Model on top of ActiveRecord,比起Delphi可以跟好的使用OO開發(fā)。
3. 組件模型更簡單
4. CoC,這個就不說了
5. expressive Ruby DSL
最后最后,說一下Delphi for PHP,做得很華麗。但是UI部分我不是很喜歡。