使用 Ruby on Rails 等豐富架構時,你可以將其視為平台或元件套件。巴德里討論了它們之間的差異,我們討論了決策會帶來哪些權衡取捨。
會議記錄
我們從馬丁詢問對 Rails(和其他類似架構)的態度開始這段對話。我們應該將它們視為平台,接受它們的優缺點嗎?還是應該將它們視為元件套件,選擇你喜歡的架構部分,而捨棄你不喜歡的? 巴德里回答說,儘管 Rails 在模組化方面已經有了很大的進展,但現在可以更輕鬆地對 Rails 進行子集化,而不是替換整個元件。例如,可以在不需要傳送或接收電子郵件的應用程式中捨棄 Action Mailer。可以將 Action Support 拉入標準 Ruby 應用程式中,並取得它提供的許多便利方法和核心擴充功能。話雖如此,例如,無法輕易地用事件驅動系統(例如 Node.js 中的系統)取代 Rails 請求回應調度週期。這是因為 Rails 是為了支援特定類型的應用程式而建構的。 馬丁輕笑,提到 Rails 是用來建構 Basecamp 的架構。
巴德里反駁說,Rails 的最佳應用範圍是與關聯式資料儲存庫對話的深度網路應用程式。換句話說,你的應用程式的使用者數量有限,無論是人類透過網路 UI 使用你的應用程式,還是其他機器透過 REST API 與你的應用程式互動,網路都不是一個偶然的元素。 巴德里進一步推測,也許問題在於人們太早決定使用架構。架構以大量的便利性取代了許多設計選項,這表示我們也許應該了解我們希望如何設計我們的應用程式,然後選擇不會禁止這些設計選擇的架構,而不是先選擇一個架構,讓它妨礙你希望如何設計系統的方式
馬丁回答說,使用架構並以一種方式設計你的應用程式的選擇可能是在一段時間之前做出的。話雖如此,架構設計人員可能會選擇不同的道路,而你可能會發現自己陷入困境。馬丁接著總結了我們到目前為止的對話,他說,如果你處於架構的最佳應用範圍,那麼將其視為平台是有道理的,而不是一開始就花費精力將自己與可能的未來變化隔離開來。 巴德里同意這個總結,並表示有些人發現他們放入的額外層有助於引導他們的設計思路。話雖如此,他個人傾向於將 Rails 視為平台。
他個人偏好使用架構作為平台,是因為過去曾有嘗試規避架構的經驗。以 .NET 中的豐富用戶端架構為例,他回憶起一次在應用程式中嘗試不使用雙向資料繫結的經驗。由於團隊中某些成員認為應該測試應用程式,他們試圖透過不使用資料繫結機制來建立一個簡約檢視。這導致相當大的混亂,因為架構並非設計為以這種方式使用,最後我們寫了過多的程式碼,並重新發明了架構的主要區塊。這是團隊若想要違背架構的本質,就必須了解的成本。也許有時值得付出這種成本,但不可避免的是,通常會產生龐大的成本。他補充說,如果團隊發現自己想要對架構進行重大變更,他們可能希望挑選最佳的程式庫並建立單點選購的應用程式。 Martin 重申重點在於根據需求做出明智的選擇,將架構用作平台或元件組件套件,而不是盲目地全面採用任一種模式,而未考量任一種方法的成本和效益。
Martin 詢問架構替你做出某些設計選擇是否有價值,以及這是否能讓團隊的新成員更快速地上手。 Badri 回應說,這是架構的一般優勢,包括 Java 世界中的 Spring 等架構。他聲稱,他個人發現人們在使用架構時遵循的常見使用模式更為重要,並舉例說明 2001 年左右,在企業 Java 世界中,幾乎每個應用程式都有自己的交易邊界實作方式,以及如何實作。這是他在參與的每個應用程式中都必須反覆學習的事情。另一方面,在 Rails 中,有一種常見的模式,即在包覆每個請求回應週期的篩選器中啟動交易,並執行回滾或提交。這種學習對於能夠從一個 Rails 程式碼庫轉移到另一個程式碼庫很有用。
Martin 呼籲人們不要將框架推入不適合它們的地方。 Badri 補充說,雖然這個觀點完全正確,但 Rails 確實在框架沒有意見的地方為各種設計選擇敞開了大門。他用他參與的幾個專案舉例說明了這一點。 第一個範例是他們會從版本控制系統中擷取提交資料,以便在應用程式的其他資料中顯示。由於需要讓應用程式在沒有此功能的情況下運作,並且需要將來自多個版本控制系統的資料全部拉入應用程式,因此他們設計了一個埠,定義了此資訊進入系統的進入點。此埠成為根據每種會傳送到此埠的資料類型適當使用轉接器來調整所有傳入資料的單一據點。
第二個範例是雙向通訊,他們建立了一個 Jabber 聊天室機器人,會從團隊聊天室中擷取與正在處理的故事相關的訊息,並將它們附加為討論串,附加到管理待辦事項的應用程式中的故事。同樣地,由於此功能並非應用程式的核心,而且他們需要讓個別團隊視需要開啟或關閉此功能,因此他們實作了一個閘道,負責處理聊天室與核心應用程式之間的所有通訊,而核心應用程式完全不知道此功能是否已設定。這讓他們能為網域邏輯的核心提供良好的隔離層級。
Martin 總結這兩個範例,表示使用 Rails 並不是要完全避免隔離。他強調你不想讓自己與平台隔離,但你確實想讓自己與外部元件隔離。 構成應用程式外部和內部部分之間的區別,讓我們回到我們開始與六角形架構模式的聊天的地方。