在前篇文章裡模擬一個小型專案的需求,利用Paste的paster工具,在src目錄裡建立骨架程式碼,新增一個mysite.eventfolder的Archetypes模組專案,執行paster addcontent contenttype之類的指令後,則可以新增型別裡的欄位資訊。熟練的話,數分鐘之內就可以搞定內容型別的雛型。為了知行合一,這裡將逐步探究程式碼的細節,了解它們的原理跟修改方法。
為了納入這個新模組,Plone系統會在「src/mysite.eventfolder」檔案系統內,依序存取數個檔案。首先,GenericSetup會讀取「mysite/eventfolder/configure.zcml」的內容,註冊extension profile。
接著,讀取interface和content目錄裡的資訊作為建立型別的依據。究竟,什麼是interface呢?它又扮演怎樣的角色呢?
元件架構介紹
如何讓系統具備擴充彈性,同時保持高的安全性,以及低的升級門檻,一直是個挑戰。
為了更接近這個聖杯,當年的開發人員將Zope2學到的經驗,轉化成Zope3的設計理念,具體的方法論稱為Zope Component Architecture(ZCA)。實作ZCA的模組被稱為Zope Toolkit(ZTK),這些方法和核心模組,也成為目前Plone的技術基礎。
Component Architecture通常被譯為「元件架構」,主要概念是將軟體依其架構與功能,分為多個獨立元件,例如Java、.Net、Mozilla XPCOM都是廣為人知的元件架構。
就元件架構而言,ZCA既不是首創,也不是獨創,它是Python軟體的開發架構,適合用來開發大型系統,加上它不只限於網頁應用程式的領域,稱之為Python Component Architecture並不為過。
Python的軟體世界是一些物件,ZCA則是一套架構方法,讓這些物件有效組建和再利用。
ZCA引入一個稱為「元件」(Component)的概念,元件本質仍是Python物件,它額外加了「介面」(Interface)物件,用來描述元件的特性和行為,例如抽象的API。不過,想要知道元件如何做到這些特性及行為的話,必須另外查看實作的程式碼。
元件介面說明
以Event Folder為例,它的介面檔案是interfaces.py或位於interfaces目錄裡,以class IeventFolder(Interface)形式來定義。介面的定義方式與傳統的Python物件定義方式很像。
不過,ZCA只是借用(有人會視為誤用)class語法,介面的定義細節仍然有其獨特之處,不要與Python物件的定義方式混淆,如圖1所示。
|
▲圖1 Event Folder的介面內容範例。 |
IEventFolder是介面的名稱,最前面的I代表interface之意,在最前面使用I符號是種慣例。IEventFolder()內接的Interface,來自於zope.interface的定義,zope.interface是ZCA的核心實作之一,也就是Zope Toolkit的模組產品。
在IEventFolder(Interface)之下,可以看到startDate和venue兩個欄位屬性值範例。載入zope.schema後,它們分別使用schema.Date()和schema.TextLine()的形式來定義,而且提供title和description之類的設定值。
不過,一般的介面內容,包括屬性值和方法兩種定義,同時也不需要載入zope.schema。接著,先利用獨立的篇幅說明介面的定義與實作宣告方式。
介面的定義與操作
利用bin/zopepy工具,可以練習建立介面定義,如圖2所示。範例裡的介面定義了startDate屬性值,還有countSignup方法。
|
▲圖2 屬性值和方法的定義範例。 |
請特別注意,startDate不需要宣告型別或起始值,countSignup也不需要self參數,這些正是與Python物件定義不同的地方。
其介面仿照一般物件的行為,因此可以沿用許多操作方法,包括__doc__查詢文件字串等,如圖3所示。
|
▲圖3 介面物件的操作範例。 |