在安卓這裡,我們總是在討論 MVC, MVP, MVVM 差異在哪,優劣在哪,和 ios 討論架構時,他們的 MVC 也有所不同,在跨足到 react 的時候,又要多了解 redux,在越來越多的框架洗禮下,我才逐漸了解到了 Uncle Bob 說的 clean architecture 到底是想表達什麼
有時看到招聘寫著,我們使用了整潔的架構,你說這對嗎?倒也不能說是不對
有趣的是,軟體裡面,能使用的架構百百種,你會聽到別人說,某某專案原本用 MVC 之後遷移到 Viper 最近在嘗試 redux 等等,這些神秘的英文名稱,是一套套軟體建構的方法,但卻不太會聽到某某專案,從 MVC 換到 clean architecture,那為什麼呢?原因很簡單,clean architecture 不是一個軟體架構!!! Clean architecture 是一個把軟體架構寫好的原則,且這個原則可以套在每一種架構上,反過來說,不論使用哪一種架構,都應該把它寫好寫乾淨,現在知道為什麼我看著招聘訊息寫說 我們使用了整潔的架構
而感到疑惑了吧
整潔架構有幾大要點
以及幾個應有的先備知識,像是繼承、抽象、封裝、多型、單一職責、開放封閉、李氏替換、介面隔離、依賴反轉等,自己去翻我前面 22 篇文章在講什麼 筆者心聲 講那麼久終於能帶到架構了
那會繼續讀下去的讀者,想必都已經了解了前面關於程式碼和物件導向的設計了,我簡單用一句話總結,請寫好讀好維護的程式XD
所謂依賴層級,指的就是在這個同心圓圖中,我們每一層的關係了
我們可以看到,主要分成了四層
由外而內,每層都會往內依賴,重要的是依賴關係只會往內,絕對不會從內部向外依賴,為什麼這點很重要,依賴是不可避免的耦合,而這種耦合就像不成熟的戀愛,總是依賴對方的人容易受傷,容易遷就自己,舉個範例吧
Mr. db = 第四層的 DB 男
Miss. cr = 第三層的 Cr 女
db 在戀愛關係中,非常的依賴 cr,是那種舔狗男友,每次 cr 說要接送,db 都得配合著修改自己的時間表,就連 cr 外派,db 都會跟著換城市找新工作,突然有天,db 要回老鄉繼承家業,db 想說,這麼多年的感情,跟 cr 講的話她一定能理解,會一起回老家的,沒想到 cr 只是淡淡的回道,既然我們的緣份到了,那就分手吧
透過上面的例子,我們學到了什麼??戀愛不能一昧舔對方,要有自己的生活,而最好的戀愛是雙向奔赴,架構是由外層向內依賴,外層的更動不會影響到內層,但內層的更動,經常會影響到外層,甚至是工具時透過抽象依賴,外層可以直接被替換掉而不影響內層
那這幾層主要是要幹嘛呢?
根據規模大小,他可能是最核心的業務規則,或是被多個專案覆用的功能或是函式,不論是哪個,這一層的特點在於它不應由外部的任何原因更動,舉個範例吧,密碼驗證規則,不論是後端還是前端,都會遵守相同的模式
在程式碼中,使用純邏輯的業務規則層,在某些專案中,會真實的有 SomeTaskUseCase
,也可能只是個 function ,不論是哪個,都應該要記住一件事,這邊只能是純邏輯、純邏輯、純邏輯,計算數字是,更新 ui 不是,更新 ui 在最外層
連接內部使用案例層,以及外部資料庫或是 ui 層的轉接層,最常見的就是資料的轉換,像是 fun ...Mapper()
或是 fun SomeDataClass.toOtherDataClass()
等等,但當然並不限於如此,舉了例子,這層作為連接層,需要將資料由使用案例適合的格式,轉換成資料庫適合的格式,但並不應該了解到資料庫的實體,什麼意思呢?
資料庫的 sql 操作會在這一層,但是資料庫建立,或是執行 sql 的接口都會在更外層
最後是框架和驅動層了,跟應用環境相關的是在這層、資料庫實作是在這層、畫面、網路等等也在這層,這層只會涉及到真實的實作,又或者說,透過層層向外,由內層定義功能邏輯,搭配外層已完成整個功能
不,根據規則你可能不需要四層,或是需要更多層級來分隔你的程式碼,不論是哪個,只需記住一件事情,每一層的溝通中間都會有一條邊界,而盡可能只讓資料類型可以穿越這條邊界
最後來到模組,模組可能存在於任意階層,也可能完全包裹了應用中的某一層級,但不論是哪種,模組都應有其內聚、開放封閉的特徵,且對外只公開抽象,使外部依賴於抽象,做進一步的依賴關係解耦
所謂的介面隔離或是抽象,不僅僅是應用在類別依賴之中,也可以包涵在功能模組之中
好的,明天會用 kmm 來再帶一次 clean architecture
In Android developer, we always discuss about MVC, MVP, MVVM, what is the different, what are their pros and cons, when I discuss MVC with ios developer, their implement is a little different, and when I start programming in react/js, I have to understand redux, with all those architecture, I start to understand what are the points of clean architecture from uncle bob
Sometimes, the recruit post says, we are using clean architecture
, well is it correct? well, you can't say they are wrong
In the software world, we have tons of architecture to choose, you might hear someone says, a project was using MVC, then move to Viper, and recently try on redux, those mystery english name is a way to implement software system, but you won't hear a project switch from MVC to clean architecture, and why is that?
The reason is simple, clean architecture is not software architecture!!!
Clean architecture is a principle to write software architecture, and this principle could fit in every architecture, in other words, all those architecture could be clean, and that is the reason I was confused that we are using clean architecture
, because that is what you should do at first
Clean architecture have following feature
The following article require some knowledge, like inheritance, abstract, encapsulate, polymorphism, Single Responsibility, open close, Liskov, interface segregation, dependency inversion ...etc, check those article in previous 22 days finally I can talk about architecture
all the detail about dependency layer is inside the concentric circles diagram
As we can see, there are four layer
From outside to inside, each layer rely on the inside layer, that is the point, the relation on dependency only goes inner, the outer change won't impact inner, but changed inside will affect outer, sometimes by using abstract dependency outer layer might be replace and not affect inner
What are those later for?
Depending on size, it might be the core of business logic, or function reused by multiple projects, whatever one of them, this layer won't affect because of any reason from an outside circle, take an example. validate password will be same for frontend or backend
In the part of code, the pure logic for business goal, in some projects, you might actually have someTaskUseCase
, it might also be function, whatever one you should remember one thing, only pure logic
This layer connect use case and implement of database or ui, the common one is data transform, like fun ...Mapper()
or fun SomeDataClass.toOtherDataClass()
, but there is more, a sample will be, sql operator will be this layer, but not building database or execute sql
The finally one is framework and driver, everything relate to application environment, database, ui, web will be this layer, this layer only deal with real implementation, from the inner part define core logic, combined with outer part to finish full function
No, you might not need all four layer, ot you might need more, the core is each layer have a bounty, all only data format can pass the bounty
In the end, here comes module, module could be any layer, and it might contain whole layer. whatever one, module should be cohesion, open close
The interface segregation, or abstract, is not only used for classes. it could be used for function module