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