Action-Domain-Responder(譯)

原文:https://herbertograca.com/2018/09/03/action-domain-responder/

這篇文章是軟件架構(gòu)編年史()的一部分,這部編年史由一系列關(guān)于軟件架構(gòu)的文章組成。在這一系列文章中,我將寫下我對(duì)軟件架構(gòu)的學(xué)習(xí)和思考,以及我是如何運(yùn)用這些知識(shí)的。如果你閱讀了這個(gè)系列中之前的文章,本篇文章的的內(nèi)容將更有意義。

MVC 誕生于 1979 年,它誕生于使用 CLI 用戶界面的桌面應(yīng)用上下文中,它暗示如果用戶外部因素導(dǎo)致數(shù)據(jù)庫變化,那么 UI 就應(yīng)該自動(dòng)地變化。同樣的模式也可以完美地應(yīng)用在稍后出現(xiàn)的 GUI 桌面應(yīng)用上。

然而,它卻和 Web 應(yīng)用一直在磨合中,因?yàn)榇蠖鄶?shù) Web 應(yīng)用不會(huì)用 UI 變化來作為服務(wù)端發(fā)生的變化的后果,它們總是從 UI 發(fā)起對(duì)服務(wù)端的調(diào)用來更新界面。

前面我已經(jīng)介紹過 MVC 及其變種(),而這篇文章將介紹另一個(gè)變種:由 Paul M. Jones 提出的 Action-Domain-Responder

2014 – Action-Domain-Responder

ADR 模式由 Paul M. Jones 于 2014 年提出,其思想和 RMR 一致,就是將 MVC 應(yīng)用于 Web REST API 上下文。ADR 最早的解釋相當(dāng)簡(jiǎn)單明了,我實(shí)在想不出更好的說法了,所以我簡(jiǎn)單地將其中部分內(nèi)容復(fù)制/粘貼到了這里,并增加了一些評(píng)論。

Action

是連接 DomainResponder 的邏輯。它使用收集自 HTTP 請(qǐng)求的輸入調(diào)用 Domain,然后使用構(gòu)建 HTTP 響應(yīng)所需的數(shù)據(jù)調(diào)用 Responder

你可以在這里找到 Action 的例子。

Domain

是組成應(yīng)用核心的領(lǐng)域邏輯的入口,它根據(jù)需要修改狀態(tài)并保存。 它可能是事務(wù)腳本、服務(wù)層、應(yīng)用服務(wù)或者其它類似的概念。

你可以在這里找到 Domain 入口的例子。

Responder

是基于自 Action 接收的數(shù)據(jù)創(chuàng)建 HTTP 響應(yīng)的展現(xiàn)邏輯。它處理狀態(tài)碼、標(biāo)頭與 Cookie、內(nèi)容、格式與轉(zhuǎn)換、模板與視圖,等等。

你可以在這里找到 Responder 的例子。

它如何工作

  1. Web 處理程序收到 HTTP 請(qǐng)求并派發(fā)給 Action;
  2. Action 調(diào)用 Domain,從 HTTP 請(qǐng)求里收集任何需要的輸入給 Domain;
  3. 然后 Action 使用創(chuàng)建 HTTP 響應(yīng)所需的數(shù)據(jù)(通常是 HTTP 請(qǐng)求和 Domain結(jié)果,如果有的話)調(diào)用 Responder;
  4. Responder 使用 Action 提供給它的數(shù)據(jù)構(gòu)造 HTTP 響應(yīng);
  5. Action 將 HTTP 響應(yīng)返回給發(fā)送 HTTP 響應(yīng)的 Web 處理程序。

Responder 基于對(duì)領(lǐng)域響應(yīng)的解析和理解來構(gòu)造 HTTP 響應(yīng),而領(lǐng)域響應(yīng)又依賴操作方法的用例。這意味著每個(gè)操作方法都需要一個(gè)特定的 Responder。如果我們將所有資源方法放到同一個(gè)控制器中,我們就需要實(shí)例化全部 Responder 并注入到控制器中,而我們?cè)谝淮?HTTP 請(qǐng)求中只會(huì)使用一個(gè) Responder,這顯然不是最優(yōu)的方案。解決方法是每個(gè)控制器只有一個(gè)方法,這種控制器和它唯一的操作方法就是 ADR 所說的 Action。

既然 Action 只有一個(gè)方法,方法名就可以使用通用的 run、execute、或是 PHP 中的 __invoke,讓這個(gè)類變成可以調(diào)用的。然而,由于其思想是將 MVC 模式應(yīng)用到 HTTP REST API 上下文,Action(控制器)名稱會(huì)被映射為 HTTP 請(qǐng)求方法,因此我們將得到名為 Get、PostPut、Delete...的 Action,清楚地表明了每個(gè) HTTP 請(qǐng)求類型調(diào)用的控制器。作為一種組織形式,一個(gè)資源的所有 Action 應(yīng)該被一起放以該資源命名的文件夾下。

與 ADR 混為一談

Anthony Ferrara 對(duì)比了 ADR 和 RMR ,認(rèn)為“它們是同樣的模式,只是細(xì)節(jié)有所調(diào)整”。

我不同意這個(gè)觀點(diǎn)。實(shí)際上我認(rèn)為 Anthony Ferrara 對(duì)它的理解是錯(cuò)誤的(他很聰明,只知識(shí)淵博,但人總有犯錯(cuò)的時(shí)候):

  1. Resource==Domain
    RMR 中的 Resource 并非 Domain,而是領(lǐng)域?qū)ο?,是領(lǐng)域?qū)嶓w,但 ADR 中的 Domain 與全部領(lǐng)域?qū)ο笥嘘P(guān),所有的實(shí)際和它們的關(guān)系作為一個(gè)整體;
  2. Representation==Responder
    RMR 中的 Representation 是發(fā)回給客戶端的響應(yīng),但 ADR 中的 Responder 是一個(gè)對(duì)象,它的職責(zé)是基于給定內(nèi)容和給定模板構(gòu)造響應(yīng)。
  3. 它和 RMR 一樣與 HTTP 耦合在一起,很難創(chuàng)建非 HTTP 界面
    既然 ADR 將 Domain 看作是一個(gè)整體而不是一個(gè)實(shí)體,Action 也不在領(lǐng)域?qū)ο髢?nèi)部,那么 Action 只會(huì)要求領(lǐng)域?qū)ο髨?zhí)行一些業(yè)務(wù)邏輯。所以 Domain 沒有與 UI 耦合,我們可以創(chuàng)建一個(gè)CLI 命令,使用領(lǐng)域?qū)ο髨?zhí)行一些任務(wù)。

我對(duì)這種模式的看法

在我看來,本文撰寫之時(shí),ADR 是 MVC 在 HTTP 請(qǐng)求/響應(yīng)范式上的最佳應(yīng)用,因?yàn)樗逦貙?HTTP 請(qǐng)求和響應(yīng)對(duì)應(yīng)到了 Domain 請(qǐng)求和響應(yīng),同時(shí)仍然保持了 Domain 和展現(xiàn)層之間完全的解耦。

HTTP 請(qǐng)求方法(期望對(duì)資源進(jìn)行的操作)被明確地連接到接收 HTTP 請(qǐng)求的代碼,因?yàn)槊總€(gè) HTTP 方法都直接映射到一個(gè)控制方法的名字。這樣做還有一個(gè)額外的好處,那就是產(chǎn)生了清晰、明確和可預(yù)測(cè)的代碼組織結(jié)構(gòu),而不是具有大量操作的控制器,這些操作通常是不相關(guān)的,命名糟糕,不可預(yù)測(cè),而且常常執(zhí)行非常類似的操作。換句話說,它避免了混亂的意大利面式的控制器和操作。

還有,它也非常好地解耦了交互自身的代碼(調(diào)用領(lǐng)域)和理解交互結(jié)果(領(lǐng)域響應(yīng))并轉(zhuǎn)換給客戶端的代碼。

然而,有一些問題仍然需要注意:

  1. 該模式專為 REST API 而設(shè)計(jì),因此,在這種形式下它還沒有完善到可以用于 HTML 界面的 Web 應(yīng)用中(例如,該如何命名創(chuàng)建資源之前展示表單的操作?);
  2. 一個(gè)控制器只有一個(gè)方法讓這種模式更啰嗦,因?yàn)?,舉個(gè)例子,相較于一個(gè)擁有四個(gè)操作(公有方法)的控制器(類),我們擁有的是四個(gè)控制器和四個(gè)操作。
  3. 為每個(gè)操作創(chuàng)建 Responder 也會(huì)讓這種模式更啰嗦。如果將領(lǐng)域響應(yīng)轉(zhuǎn)換成 HTTP 響應(yīng)的邏輯很簡(jiǎn)單,我們應(yīng)該思考一下是否值得使用 Responder。不用 Responder 意味著我們可以在每個(gè)控制器中擁有多個(gè)方法,每個(gè)方法依然與一個(gè) HTTP 方法對(duì)應(yīng)。

關(guān)于第二點(diǎn)和第三點(diǎn), Paul M. Jones 自己也承認(rèn)并同意有些情況下使用簡(jiǎn)化的模式是可以接受的,盡管不那么優(yōu)雅,但足以應(yīng)對(duì)手頭上的上下文。

關(guān)于第一點(diǎn),我認(rèn)為該模式可以輕松地進(jìn)行擴(kuò)展,就能完全應(yīng)用于 HTML 界面:我們可以模擬一些 REST API 沒有的額外的 HTTP 方法,專門處理 HTML 請(qǐng)求。例如,我們可以在一個(gè) REST API 中使用 PUTPOST 來創(chuàng)建和/或更新資源,而這就是該資源所需的全部方法,可是對(duì)于 HTML 界面來說,我們?cè)诎l(fā)送 PUTPOST 之前需要一個(gè)表單,但是沒有 HTTP 方法專門供客戶端請(qǐng)求創(chuàng)建資源或編輯的表單。然而,我們可以使用一個(gè)帶有 createedit 標(biāo)頭的 GET 請(qǐng)求來模擬它,前端控制器可以解析該請(qǐng)求并轉(zhuǎn)發(fā)給對(duì)應(yīng)的名為 CreateEdit 的操作,然后這些操作將回復(fù)對(duì)應(yīng)的 HTML 表單。然而,對(duì)于創(chuàng)建額外的自定義 HTTP 方法,我們要非常小心和克制…否則可能導(dǎo)致產(chǎn)生過多的自定義 HTTP 方法和一大堆綁定到意大利面條式的操作的自定義 HTTP 方法?。∫虼?,小心謹(jǐn)慎地采納最后這個(gè)建議。

引用來源

2014 – Paul M. Jones – Action Domain Responder
2014 – Paul M. Jones – Action-Domain-Responder (Vimeo)
2014 – Paul M. Jones – The Template Is Not The View: A Brief Introduction to ADR(Youtube)
2014 – Paul M. Jones – Action-Domain-Responder: A Refinement of MVC (slides)
2014 – Anthony Ferrara – Alternatives To MVC
2018 – Paul M. Jones – Model View Controller and “Model 2”
2018 – Paul M. Jones – Comparing “Model 2” MVC to ADR
2018 – Paul M. Jones – Tradeoffs in ADR
2018 – Paul M. Jones – Objections to ADR

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 國(guó)家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說閱讀 12,394評(píng)論 6 13
  • 在iOS開發(fā)中經(jīng)常會(huì)涉及到觸摸事件。本想自己總結(jié)一下,但是遇到了這篇文章,感覺總結(jié)的已經(jīng)很到位,特此轉(zhuǎn)載。作者:L...
    WQ_UESTC閱讀 6,249評(píng)論 4 26
  • 1 幾年前,坐過一次從北京到上海的火車,無座,十多個(gè)小時(shí),站著,直到上海。那時(shí),就發(fā)誓,只要我活著,永遠(yuǎn)不會(huì)再坐無...
    陳清偉閱讀 34,085評(píng)論 1 1
  • OpenOffice組件docx/doc轉(zhuǎn)html 準(zhǔn)備工作 CentOS 安裝OpenOffice資源準(zhǔn)備ope...
    人形大叔閱讀 2,788評(píng)論 0 1
  • 男朋友月入6000,每月只留1500其他都給他父母,想讓他買個(gè)衣服什么的,他就說沒錢,說自己也不夠,說把錢給家里。...
    小饞貓的傻傻狗閱讀 344評(píng)論 2 0

友情鏈接更多精彩內(nèi)容