Showing posts with label architecture. Show all posts
Showing posts with label architecture. Show all posts

Sunday, June 16, 2019

Architecture: Cut horizontally v.s. Cut vertically

關於 software architecture ,我最近發現了有一塊,過去我總是沒有想得很清楚的地方: cut horizontally 與 cut vertically 的比較。仔細想想,這個也不是什麼太新的觀念。一般來講,像公司內部的分工,也有類似的兩種概念

cut vertically 近似於公司切分事業部的概念: A 部門負責 a 產品,所以 A 部門就盈虧自負。在 software 就是切分出 Component, bounded context 。也可以稱之為 package by component/ package by feature

cut horizontally 比較近似於公司內統一採購、發包的概念: 公司完成工作,有時會透過與第三方協力廠商共同完成。與第三方的關係,會透過統一的採購、發包專人來做。這在 software 就是切分出 Application, Adapter 的層次。可稱之 package by layer 。 cut horizontally 比較難找到很巧妙的類比,不過,對照 cut vertically 之後,應該比較容易想象。

無論是 cut vertically 或是 cut horizontally ,都要設法讓 components 或是 module 可以解耦(decoupled)

在 cut horizontally 的情況,應用的技巧,主要是 Dependency Injection 。
然而在 cut vertically 的情況,應用的技巧則是 events/shared kernel 等。

Monday, February 4, 2019

From REST to CQRS with Clojure, Kafka, and Datomic

Clojure/conj 2015 年的 conference talk --- From REST to CQRS with Clojure, Kafka, and Datomic 是我 2019 年所看到第一篇深受啟發的 talk ,也有 youtube  影片。

首先作者先探討 Restful API  的一些問題:
1.  modeling - jamming every operation into CRUD on some resources is often unnatural, creating impedance mismatch. 
Restful API 可以視為是模仿 Database 的 CRUD 介面 (post, get, patch, put) ,然而,這個 modeling 在本質上,未必適合對各式各樣的問題做建模。
2. mutability semantics
Restful API 隱含了 mutable 語意
3. the kingdom of nouns for distributed system 
最後就是有太多的 API ,然後需要有類似 swagger 之類的 API document 系統 …
4. integration 
integration by API 比 integration by ETL 好一些,但是,還是有許多缺點

然後,作者 (Bobby Calderwood) 提出了一個應用 CQRS + Event sourcing 來設計系統的架構 (Commander Pattern),如下圖:



















新的架構處理了許多舊有的問題:
1. modeling 
web services 的部分只對 communication semantic 做建模,所以只有三種,而非 resources * CRUD 。communication semantic 是指 /command /update /query 三種語意。
2. immutable semantics
/command API 會寫入 command log 。這個 command log 對使用者的 intention 做完整地記錄,相較於儲存進資料庫裡的資料, command log 有更完整的 command story
3. too many APIs
因為新架構的 http endpoint 只有三種: /command /update /query 。
4. integration
新的架構裡可以 integration by events ,因為有儲存下 command log 。要整合的時候,其它系統去訂閱 command log 就可以完整地拿到系統的 states

心得感想:
(*) end-to-end principle
在這個架構裡, Web services 層只用來處理 communication 。 Restful API 的 resources 名稱,其實算是一種 domain semantics,應該要放到 Business Logic 層來實現。這其實很像網路世界的 end to end principle ,因為 Client 與 Business Logic 就像是溝通的兩個端點 ,針對應用 (application) 設計的種種特性 (features),應該要在這兩端來加以實現,而不是在中間的 Web services 層實現。

(*) We shape our tools and thereafter our tools shape us. 
Restful API 的設計,有點像是使用了 SQL/relational database 之後的思維模型會構思的設計。而這個 Commander Pattern 則是使用了 Datomic 之後的思維模型會構思的設計。

Saturday, December 29, 2018

The Unintentional Side Effect of a Bad Concurrency Model

這篇 The Unintentional Side Effect of a Bad Concurrency Model 出自 Joe Armstrong 的 blog 。文章裡提到的 Erlang 世界觀,跟 Robert C. Martin 主張的 Clean Architecture 相左。 Robert C. Martin 認為:「 micro-services 只是一種 deploy 的選項 ,並不是 Architecture 。」然而在 Erlang 的世界觀卻不這麼認為,在 Erlang programmer 的世界觀認為:
(1) micro-services 的設計,才應該是 default 的選項。我們應該要透過不停地在系統中加入新的小型獨立的 communicating objects 來讓系統成長 (micro-services),而不是把「不需要溝通」的程式愈寫愈大 (monolithic)。
(2) 模組與模組之間,應該要透過 communication protocol/message 來溝通,而不是依賴於 API 。

而作者的結論是:『為什麼世界上大部分的程式都不是用 erlang 的世界觀在開發,主要就是因為大部分的其它語言都沒有一個好的 concurrency model ,於是就造成了一種未意料到的副作用。』

Sequential languages are designed to write sequential programs, and the only way for a sequential program to grow in functionality is for it to get larger. It's technically difficult to split it into cooperating processes so this is not usually done. The concurrency in the application cannot be used to structure the application.

We should grow things by adding more small communicating objects, rather than making larger and larger non-communicating objects.

Concentrating on the communication provides a higher level of abstraction than concentrating on the function APIs used within the system. Black-box equivalence says that two systems are equivalent if they cannot be distinguished by observing their communication patterns. Two black-boxes are equivalent if they have identical input/output behavior.

Thursday, August 2, 2018

Clean Micro-service Architecture

Clean Micro-service Architecture 又是 Robert C. Martin 的文章。

大意如下:

Clean Architecture 與 microservices 是兩個正交的概念

  • Clean Architecture 是指軟體系統的設計要可以清楚地區分成 entity, use cases, controller & gateway & presenter 這三個圈圈。之後才可以不斷地配合需求而修改。
  • microservices 是一種 deployment option (布署選項) ,而且這個布署的選項有它的 trade-off 。此外,還有其它的布署選項。使用不同的布署選項,是為了達成不同的 scalability  。

其它相關的布署選項還有:

  • 在同一個 thread 裡的 jar ,彼此透過函數來溝通。 
  • 在同一個 process 裡的 thread ,彼此透過 mailbox 或是 queue 溝通
  • 在同一台 machine 裡的不同 process ,彼此透過 socket 溝通
  • 在 Internet 上不同的 services ,彼此透過 asynchronous API 溝通
引述文章裡的一小段話 --- The deployment model is a detail. Micro-services are deployment option, not an architecture. 作者主張:「開發軟體系統,要視實際的需求,再來決定要用哪一種合適的布署選項。」

注意: jar 也可以達成 independent deployability (可獨立布署性) 和 hot swapping (程式碼熱抽換。) 所以也是相關的 deployment option