架構整潔之道導讀(四)第25章層次與邊界-圖 25.3 疑惑澄清

最近收到讀者反饋审丘,《架構整潔之道》第 25 章“層次與邊界”中,圖 25.3 和解釋這張圖的一段文字的描述讓人很費解。

圖25.3 修正后的設計圖

如果我們進一步查看 GameRules 內(nèi)部勘天,就會發(fā)現(xiàn) GameRules 組件的代碼中使用的 Boundary 多態(tài)接口是由 Language 組件來實現(xiàn)的;同時還會發(fā)現(xiàn) Language 組件使用的 Boundary 多態(tài)接口由 GameRules 代碼實現(xiàn)。

讀者的疑惑是 GameRules 和 Language 分別定義接口讓對方實現(xiàn)脯丝,那么這兩個組件不就形成雙向依賴了嗎商膊?

我們僅憑直覺就知道雙向依賴肯定是錯的,那么這句話到底該作何解釋巾钉?為了排除翻譯出錯的可能性翘狱,我仔細比照了原文,確定了譯文并不損失原意砰苍。

If we were to look inside GameRules, we would find polymorphic Boundary interfaces used by the code inside GameRules and implemented by the code inside the Language component. We would also find polymorphic Boundary interfaces used by Language and implemented by code inside GameRules.

我回頭翻閱了當時技術審校的文章潦匈,遺憾地發(fā)現(xiàn)自己確實疏漏了對此處的解釋,所以我重新翻閱了書中和邊界(Boundary)相關的章節(jié)赚导,比如第 22 章的“整潔架構”和第 24 章的“不完全邊界”茬缩,給出一個牽強的解釋:我認為 Bob 大叔在這里提到的 Boundary 多態(tài)接口(polymorphic Boundary interfaces)指的是系統(tǒng)在構建完全邊界時需要的 inputBoundary 和 outputBoundary 的。但是不管如何吼旧,也不可能出現(xiàn)他說的低級別的組件(此處的 Language)定義接口讓高級別的組件(GameRules)去實現(xiàn)的情況凰锡。

為了解決讀者心中的疑惑,我寫了封郵件給 Bob 大叔圈暗。這封郵件的內(nèi)容重點在詢問 GameRules 為什么會有對 Language 的依賴掂为。Bob 大叔的回復得很迅速,內(nèi)容如下:

The secret here is that the polymorphic interfaces used by Language and implemented by Game Rules are contained within Game Rules. This keeps the arrows pointing in the same direction.

他強調(diào) Language 使用的多態(tài)接口其實是定義在 GameRules 當中的员串,所以依賴方向依然是從 Language 指向 GameRules 的勇哗。看到這樣的回復寸齐,我還是有些迷惑欲诺,不過認真思考了一段時間,我大概知道這里的誤解到底是什么了渺鹦。

其實答案就隱藏在第 22 章“整潔架構”里圖22.2 一個基于 Web 的扰法、使用數(shù)據(jù)庫的常見 Java 程序

結合這張圖毅厚,我們不難總結出 Language和 GameRules 的依賴關系塞颁,邊界和高層次的接口定義,這里面最需要澄清的點就是“使用”并不意味著“定義”吸耿,而只是引用祠锣。為了確保我的理解正確,我引用了原文并逐行提出我的問題珍语,然后畫了一些圖锤岸,發(fā)送一封確認郵件。Bob 大叔很仔細地回復了我的問題板乙。我把郵件原文列在底下是偷。其中拳氢,Q 代表我的問題,Answer 是 Bob 大叔的回答蛋铆。

"The diagram in Figure 25.3 has gotten a little complicated, but should contain no surprises. The dashed outlines indicate abstract components that define an API that is implemented by the components above or below them. For example, the Language API is implemented by English and Spanish."

Q1: Language components define interfaces that should be implemented by its derivates like English and Spanish that are below the Language component. So why you emphasise ABOVE them?

Answer: In Figure 25.3 you’ll see SMS and Console above Text Delivery. Text Delivery does not actually exist as an independent module. It is an abstraction, or a set of conventions, that both SMS and Console adhere to. English and Spanish appear below Language. Again, Language does not actually exist as a module. English and Spanish simply adhere to the conventions that we call Language.

"GameRules communicates with Language through an API that GameRules defines and Language implements. Language communicates with TextDelivery using an API that Language defines but TextDelivery implements. The API is defined and owned by the user, rather than by the implementer."

Q2: GameRules defines API (interface) that Language component implements, does it mean GameRules and Language are separated components?

Answer: Not quite. English and Spanish are separate from Game Rules and both implement the API defined in Game Rules. The Language abstraction is draw there to denote that English and Spanish follow the conventions that Game Rule and Text Delivery require.

"If we were to look inside GameRules, we would find polymorphic Boundary interfaces used by the code inside GameRules and implemented by the code inside the Language component. We would also find polymorphic Boundary interfaces used by Language and implemented by code inside GameRules."

Q3: In Chapter 22, there is figure 22.2 a typical scenario for a web-based Java system utilising a database.


figure 22.2 a typical scenario for a web-based Java system utilising a database

Here, I mark connections to explain my understanding for "used by" and "implemented by". So "used by" is not meaning "defined by", right?

Answer: Right.

If my understanding is correct, how about the diagram I draw as follow? does it explain the secret you mentioned above?


Boundary interfaces

"If we were to look inside of Language, we would find the same thing: Polymorphic Boundary interfaces implemented by the code inside TextDelivery, and polymorphic Boundary interfaces used by TextDelivery and implemented by Language."

"In each case, the API defined by those Boundary interfaces is owned by the upstream component.”

Q4: In GameRules and Language components context, upstream component means the GameRules? In Language and TextDelivery components context, upstream means the Language?

Answer: Yes. Upstream means “higher level".

當我把郵件完整地轉發(fā)給讀者后馋评,他表示“我看了 Bob 大叔的回答,感覺對依賴反轉的認識又深了一層刺啦。不留特,應該說看了你的回答(商業(yè)互吹)。抽象出的接口玛瘸,我從來沒想過接口的歸屬問題蜕青,這么看來就合理了『ǎ”

小結

以后我們在設計組件時一定要關心邊界和接口定義的歸屬右核。它代表著依賴反轉原則在更大的架構層面上的運用。


于 2019-10-27

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末渺绒,一起剝皮案震驚了整個濱河市贺喝,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌宗兼,老刑警劉巖躏鱼,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異殷绍,居然都是意外死亡染苛,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門篡帕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來殖侵,“玉大人贸呢,你說我怎么就攤上這事镰烧。” “怎么了楞陷?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵怔鳖,是天一觀的道長。 經(jīng)常有香客問我固蛾,道長结执,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任艾凯,我火速辦了婚禮献幔,結果婚禮上,老公的妹妹穿的比我還像新娘趾诗。我一直安慰自己蜡感,他們只是感情好蹬蚁,可當我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著郑兴,像睡著了一般犀斋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上情连,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天叽粹,我揣著相機與錄音,去河邊找鬼却舀。 笑死虫几,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的挽拔。 我是一名探鬼主播持钉,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼篱昔!你這毒婦竟也來了每强?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤州刽,失蹤者是張志新(化名)和其女友劉穎空执,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體穗椅,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡辨绊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了匹表。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片门坷。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖袍镀,靈堂內(nèi)的尸體忽然破棺而出默蚌,到底是詐尸還是另有隱情,我是刑警寧澤苇羡,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布绸吸,位于F島的核電站,受9級特大地震影響设江,放射性物質(zhì)發(fā)生泄漏锦茁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一叉存、第九天 我趴在偏房一處隱蔽的房頂上張望码俩。 院中可真熱鬧,春花似錦歼捏、人聲如沸稿存。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挠铲。三九已至冕屯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間拂苹,已是汗流浹背安聘。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留瓢棒,地道東北人浴韭。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像脯宿,于是被迫代替她去往敵國和親念颈。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 久違的晴天连霉,家長會榴芳。 家長大會開好到教室時,離放學已經(jīng)沒多少時間了跺撼。班主任說已經(jīng)安排了三個家長分享經(jīng)驗窟感。 放學鈴聲...
    飄雪兒5閱讀 7,523評論 16 22
  • 今天感恩節(jié)哎,感謝一直在我身邊的親朋好友歉井。感恩相遇柿祈!感恩不離不棄。 中午開了第一次的黨會哩至,身份的轉變要...
    迷月閃星情閱讀 10,567評論 0 11
  • 可愛進取躏嚎,孤獨成精。努力飛翔菩貌,天堂翱翔卢佣。戰(zhàn)爭美好,孤獨進取菜谣。膽大飛翔珠漂,成就輝煌晚缩。努力進取尾膊,遙望,和諧家園荞彼「粤玻可愛游走...
    趙原野閱讀 2,731評論 1 1
  • 在妖界我有個名頭叫胡百曉,無論是何事鸣皂,只要找到胡百曉即可有解決的辦法抓谴。因為是只狐貍大家以訛傳訛叫我“傾城百曉”暮蹂,...
    貓九0110閱讀 3,266評論 7 3