---
title: "從架構到設計 - 重新思考 Rails 架構"
date: 2024-08-30T00:00:00+08:00
publishDate: 2024-08-30T00:00:00+08:00
lastmod: 2024-06-02T17:03:47+08:00
tags: ["Rails","Domain-Driven Design","設計","Clean Architecture"]
series: "rethink-rails-architecture"
toc: true
permalink: "https://blog.aotoki.me/posts/2024/08/30/rethink-rails-architecture-from-architecture-to-design/"
language: "zh-tw"
---


不論是資料驅動（Data-Driven）還是領域驅動（Domain-Driven）的角度，思考的範圍仍侷限在單一功能，如果要討論一個完整系統，就需要再繼續往上提升層級到架構（Architecture）的角度進行思考。

> 架構問題對於完整的[領域驅動設計（Domain-Driven Design）](https://zh.wikipedia.org/zh-tw/%E9%A0%98%E5%9F%9F%E9%A9%85%E5%8B%95%E8%A8%AD%E8%A8%88)仍屬於戰術（Tactical）問題，也就是開始實踐的部分，還需要再往上思考策略（Strategic）問題，關於軟體的目的的思考。

<!--more-->

## 策略{#strategic}

我認為在討論架構之前，還是需要從「策略」出發，假設我們給了錯誤的策略，那麼後續的戰術（架構、設計）都可能會是錯誤的。

然而，針對領域驅動設計中策略的討論並不好找到學習資源。原因在於這些策略大多是根據商業需求分析得來，比起找到一個「標準做法」更需要的是深入分析的能力。以常見的事件風暴（Event Storming）為例子，就會將所有利害關係人（使用者、產品經理、工程師）找出來一起腦力激盪，釐清系統的脈絡。

如果要用很粗略的角度去看待這個問題，就是我們該如何釐清使用者對於產品的需求，這一點在不同的理論（如：敏捷開發）也都是一樣的，如何有系統的進行，就可以使用上述提到的工具來釐清。

同樣的，既然是策略層級的問題，也需要對齊公司的目標、願景，並以更全面的方式看待，而不是只在某個功能、產品、部門層級去判斷。

## 架構{#architecture}

當我們決定策略後，大致上會知道系統開發追求的目標是什麼（快速更新、穩定等等）在選擇技術的搭配上就會明確很多，那麼架構就會相對容易的成形。

舉例來說，假設公司未來的重點是放在發展人工智慧（AI）相關的應用，並且要自己訓練模型提供 RESTful API 服務，以追求穩定的企業客戶為主。在這樣的前提下，對於架構的選擇就會偏向能夠處理大量資料的資料庫、容易搭建 RESTful API 的框架等等條件。

直到這些議題被確定下來，我們才能夠正式進入到軟體層面的架構議題。當我們選擇了 Rails 框架作為開發工具，背後有怎樣隱藏的意義呢？

舉例來說，入門 Rails 框架並不困難且容易修改、擴充，但是對於過於複雜的系統就沒辦法很好的處理，因此很適合需要快速開發提供高度客製化選項，但是對功能需求不複雜的情況，因此 Rails 一直都接案公司偏好的框架之一。

然而，每個系統都會變複雜、擴大，後續就會需要討論替換掉 Rails 或者設計更複雜的機制、架構來處理這些問題。

> 以 DHH 所在的 37signals 來說，產品複雜度都是有意控制在某個規模下，因此 Rails 一直可以適用，但是其他像是 Twitter、Shopify 等就不一定，最後發展出更換語言、多語言混用等等不同的方式。

## 設計{#design}

架構跟設計很像，到底差在哪裡呢？我在 2023 年的 [RubyConf TW 演講](https://speakerdeck.com/elct9620/2023-rubyconftw-rethink-rails-architecture) 用細節程度來作為區分。這是因為在討論架構時，我們通常是用大分類、設計模式等方式討論，然而在撰寫系統設計（System Design）文件時，則會詳細的把介面、流程圖、資料庫等等詳細的定義。

即使如此，設計這一個概念仍是抽象的。剛好在 2024 年初我看了 [Food & Design](https://www.kickstarter.com/projects/muris/food-and-design-a-documentary-on-food-design) 這部紀錄片，最開始的時候提到「設計不是產出（Outcome）而是過程（Process）」很適合用來解釋我們在進行系統設計該做的任務。

跟設計師在進行設計一樣，我們透過設計的過程，去探索軟體的使用者如何使用這個系統，並思考如何讓使用者在過程中是流暢的。那麼，要實踐這樣的過程，就會發現從策略的制定、架構的選擇到設計的細節，都會息息相關。

