【已發(fā)表于《程序員》2007年第1期,全名《程序員的私人外包專(zhuān)家——探索CodeSmith代碼生成器》,因篇幅限制,雜志上略有刪減】
引言
如果機器貓是個(gè)軟件開(kāi)發(fā)人員,那么它一定能從口袋里掏出如圖1所示的軟件,簡(jiǎn)潔明快的界面上僅有幾個(gè)必要的輸入控件,只要用鼠標輕輕點(diǎn)擊這個(gè)按鈕,硬盤(pán)便會(huì )像著(zhù)了魔一樣瘋狂地發(fā)出一陣吱吱的叫聲,數分鐘后,當這個(gè)世界重新安靜下來(lái)時(shí),一款全新的軟件誕生了!
圖1,傳說(shuō)中機器貓的軟件開(kāi)發(fā)解決方案
不過(guò)就目前的技術(shù)水平來(lái)說(shuō),這還只能算是“癡人說(shuō)夢(mèng)”。那么,有沒(méi)有什么軟件可以減輕程序員的重復性勞動(dòng),將“百忙”變?yōu)?#8220;不忙”,使得大家有更多的時(shí)間來(lái)陪伴家人和女友呢?現在軟件行業(yè)不是流行“外包”嗎?大公司外包給小公司、小公司外包給個(gè)體戶(hù),那么程序員可以將手頭上一部分編碼工作外包給誰(shuí)呢?除了Ctrl+C、Ctrl+V這對著(zhù)名的孿生兄弟外,我想CodeSmith會(huì )是一個(gè)更好的選擇。
What
什么是CodeSmith?從字面上直譯可以看作“代碼工匠”。這倒是個(gè)很擬人化的名稱(chēng),顧名思義,CodeSmith的目標就是根據模板生成規范可用的代碼,為程序員減輕工作負擔。
程序員是軟件開(kāi)發(fā)團隊中的最小單位,有什么任務(wù)都只能自己一肩扛起而無(wú)法再往下分配。但是程序員又是聰明的,他們總是能找到很多美妙的辦法來(lái)減輕壓力,代碼生成器就是一個(gè)典型的例子。事實(shí)上,Visual Studio 2005本身就自帶了代碼生成的功能,比如您在代碼編輯器中輸入關(guān)鍵字“for”,然后直接按Tab鍵,代碼生成器便會(huì )為您生成好一段模板式的代碼:
圖2,Visual Studio 2005的代碼生成功能
Visual Studio 2005還能自動(dòng)生成其它更多形式的代碼,但終究不如CodeSmith那樣強大和豐富,畢竟術(shù)業(yè)有專(zhuān)攻嘛。CodeSmith是以模板作基礎來(lái)為程序員生成高質(zhì)量代碼的,模板可大可小,CodeSmith一次能夠生成的代碼量也就可多可少,這主要靠具體問(wèn)題具體分析。
CodeSmith的模板是以“.cst”為后綴名的代碼文件,其風(fēng)格非常類(lèi)似于A(yíng)SP.NET。模板中除了大量固定的代碼以外,還有遍布于各處的元數據(metadata)。固定代碼就是會(huì )被CodeSmith原封不動(dòng)地輸出的代碼,而元數據則可以被看作是模板中的變量。那么現在我們就通過(guò)一個(gè)簡(jiǎn)單的模板文件來(lái)了解CodeSmith的工作原理:
1<%@ Template Language="C#" TargetLanguage="C#" Description="Demonstrates the most basic template." %>
2<%@ Property Name="SampleBooleanProperty" Type="System.Boolean" Default="True" Category="Options" Description="This is a sample boolean property." %>
3<%@ Property Name="SampleStringProperty" Type="System.String" Default="SampleString" Category="Options" Description="This is a sample string property." %>
4// This class generated by CodeSmith on <%= DateTime.Now.ToLongDateString() %>
5public class SimpleTemplate
6{
7 public SimpleTemplate() : base()
8 {
9 }
10 <% if (SampleBooleanProperty) { %>
11
12 private void <%= SampleStringProperty %>()
13 {
14 // Do something
15 }
16 <% } %>
17}
如果您了解ASP.NET的語(yǔ)法,那么就很好理解CodeSmith模板文件了。第一條語(yǔ)句:
<%@ Template Language="C#" TargetLanguage="C#" Description="Demonstrates the most basic template." %>
是模板文件的聲明語(yǔ)句,每個(gè)模板文件都必須以此作為開(kāi)頭,它包含了必要的聲明信息,如模板語(yǔ)言、目標語(yǔ)言以及模板描述。除必需的“Language”屬性以外,CodeSmith還提供7個(gè)可供模板聲明使用的屬性:
● Description:作為模板的描述性信息并可以在該模板的ToolTip中顯示;
● Inherits:盡管默認情況下所有模板都繼承自CodeSmith.Engine.CodeTemplate,但仍然可以由您來(lái)指定模板繼承自其它類(lèi)(只要該類(lèi)直接或間接地繼承自CodeSmith.Engine.CodeTemplate);
● Src:該屬性使您能夠將其它類(lèi)的功能添加進(jìn)當前模板,您能夠用這個(gè)屬性來(lái)實(shí)現“代碼隱藏”模型;
● Debug:當該屬性被設置為T(mén)rue時(shí),您就可以使用System.Diagnostics.Debugger.Break方法來(lái)為您的模板設置斷點(diǎn);
● OutputType:該屬性用于指定以“Normal”、“Trace”或“None”方式輸出模板;
● LinePragmas:當該屬性被設置為T(mén)rue時(shí),模板錯誤將指向源代碼;設置為False時(shí),模板錯誤將指向編譯后的代碼;
● ResponseEncoding:用于設置模板及輸出的編碼,該屬性支持來(lái)自于System.Text.Encoding.GetEncoding方法的值,默認情況下為ASCII。
模板中的代碼可以分為三個(gè)部分:靜態(tài)、系統生成和動(dòng)態(tài)的。靜態(tài)代碼就是系統將原封不動(dòng)地輸出的代碼,例如前面代碼示例中的:
public SimpleTemplate() : base()
CodeSmith可以自動(dòng)生成部分代碼,例如示例中的:
// This class generated by CodeSmith on <%= DateTime.Now.ToLongDateString() %>
CodeSmith將<%= %>標記中間的部分作為計算表達式,在運行時(shí)計算該表達式并將結果輸出到代碼中相應的位置。CodeSmith中的屬性用以實(shí)現用戶(hù)自定義的輸出內容,例如示例中的:
<%@ Property Name="SampleStringProperty" Type="System.String" Default="SampleString" Category="Options" Description="This is a sample string property." %>
屬性具有名稱(chēng)和類(lèi)型,這是必需的內容,另外還可以給屬性設置一個(gè)默認值,添加一些描述性說(shuō)明以便于用戶(hù)在使用該屬性時(shí)能夠迅速地了解其用途和用法。使用屬性時(shí)仍然會(huì )用到<%= %>標簽,在該標簽中插入需要的屬性名即可,例如:
private void <%= SampleStringProperty %>()
盡管模板文件的內容似乎要比所需要的源代碼復雜得多,但這是一勞久逸的工作,因為您可以用模板生成無(wú)數代碼,當初編輯模板時(shí)花費在編寫(xiě)動(dòng)態(tài)內容及屬性上的辛苦付出將在日后使用模板時(shí)得到豐厚的匯報!
當前最新版本是于11月8號發(fā)布的V4.0。作為一次大的版本升級,CodeSmith理所當然地給我們帶來(lái)了新的特性,這些新特性一方面使CodeSmith成為更加強大的軟件,另一方面也使得程序員們更加青睞這位得力助手。目前CodeSmith V4.0已經(jīng)很好地集成進(jìn)Visual Studio 2005,這樣一來(lái),程序員就能夠更加方便地使用它了。那么,就讓我們來(lái)看看,CodeSmith還為我們帶來(lái)了哪些振奮人心的新特性吧:
● CodeSmith Project:CSP的出現使得您無(wú)論在Visual Studio 2005、MSBuild、Windows Explorer、命令行、批處理文件或是CodeSmith自身環(huán)境下都可以以輕松、一致的方式自動(dòng)地生成代碼;
● ActiveSnippets:比Visual Studio 2005的Snippet更加強大,可以通過(guò)執行邏輯處理或是訪(fǎng)問(wèn)復雜的原數據來(lái)控制代碼片段的輸出;
● CodeSmith Maps:創(chuàng )建字典式的映射,例如SQL與C#的數據類(lèi)型映射;
● .netTiers 2.0:增強的.netTiers模板;
● Extended Property Management:可以在CodeSmith Studio中編輯或者添加模式擴展屬性;
● Property Persistence:現在CodeSmith可以記住您最近一次執行模板時(shí)的屬性值;
● CodeSmith Studio:改進(jìn)了智能感應并全面提升性能;
How
怎樣使用CodeSmith?不論我說(shuō)的多么天花亂墜,如果不告訴大家一些基本常用的使用方式,那么本文就起不到廣而告之的作用。那么我就以簡(jiǎn)單的例子來(lái)向大家演示如何使用CodeSmith來(lái)減輕開(kāi)發(fā)人員的工作負擔。
您可以從CodeSmith Tool LLC的官方網(wǎng)站上下載該軟件,推薦使用Professional版,安裝完畢之后您會(huì )看到有兩個(gè)圖標,一個(gè)是CodeSmith Explorer,另一個(gè)是CodeSmith Studio,前者是利用模板輸出代碼的,而后者則用于編輯模板。我們先運行CodeSmith Explorer來(lái)看看如何通過(guò)模板得到我們想要的代碼。
圖3,CodeSmith Explorer界面
運行CodeSmith Explorer就能看到如圖3所示的界面,點(diǎn)擊Collections前面的加號就會(huì )看到有個(gè)ArrayList.cst的節點(diǎn),如圖4所示:
圖4,選中ArrayList.cst模板
雙擊該節點(diǎn),便會(huì )彈出CodeSmith的輸出窗口,在窗口的左邊是屬性輸入框,您可以根據自己的需要設定各屬性的值,然后只需輕輕點(diǎn)擊下面的Generate按鈕,CodeSmith就能立刻為您獻上一份長(cháng)長(cháng)的源代碼,如圖5所示:
圖5,使用CodeSmith生成源代碼
該例子所生成的源代碼共有2302行,想想如果手工輸入這么多代碼需要花費多少時(shí)間呢?而使用CodeSmith則僅花費了不到1分鐘時(shí)間,其魅力則就不言而喻了!
如果您對CodeSmith提供的模板感到不太滿(mǎn)意,或者您需要根據自己的需求來(lái)制作相應的模板,則可以使用CodeSmith Studio來(lái)新建或編輯現有代碼模板,例如,你對剛才我們使用到的ArrayList.cst模板感到不甚滿(mǎn)意,覺(jué)得自己有更好的創(chuàng )意,那么你可以運行CodeSmith Studio,然后在右邊的文件列表中找到并打開(kāi)ArrayList.cst,還記得剛才我介紹的那些模板元素以及它們各自的特性和用途嗎?好吧,現在就開(kāi)始動(dòng)手根據您自己的想法來(lái)完善這個(gè)模板吧。
圖6,編輯代碼模板
在這里因為篇幅有限,所以我只是使用了一個(gè)最簡(jiǎn)單的例子來(lái)向大家展示使用CodeSmith的好處,其實(shí)CodeSmith的強大遠不僅僅是輸出這樣簡(jiǎn)單的代碼文件,記住,CodeSmith是基于模板生成代碼的,因此,套用那句“人有多大膽,地有多高產(chǎn)”的話(huà)來(lái)說(shuō)就是:“模板有多強大,代碼就有多豐富!”
Why
為什么向您推薦CodeSmith?可千萬(wàn)別把我當成了托兒,我可沒(méi)有收取CodeSmith Tools LLC任何物質(zhì)上以及精神上的報酬,不過(guò)是為了和廣大開(kāi)發(fā)著(zhù)朋友們分享一款優(yōu)秀的專(zhuān)業(yè)軟件而已。
其實(shí)有很多代碼都是不需要我們自己從頭到尾親自寫(xiě)一遍的,尤其是在工作中,為什么不能用更少的時(shí)間完成更多的事情呢?程序員從事的是腦力勞動(dòng),我們應該充分運用我們的頭腦來(lái)找到解決問(wèn)題的更快更好的辦法,只有當我們能夠很好地解決自己工作中的問(wèn)題的時(shí)候,我們才能夠為我們的用戶(hù)提供能很好解決他們面臨的問(wèn)題的解決方案。Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1510510