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ù)庫(kù)變化顾犹,那么 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è)方法借笙,方法名就可以使用通用的 runexecute较锡、或是 PHP 中的 __invoke业稼,讓這個(gè)類變成可以調(diào)用的。然而蚂蕴,由于其思想是將 MVC 模式應(yīng)用到 HTTP REST API 上下文低散,Action(控制器)名稱會(huì)被映射為 HTTP 請(qǐng)求方法,因此我們將得到名為 Get骡楼、Post熔号、PutDelete...的 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ū)ο螅穷I(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)椋e個(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 方法2芴А溉瓶!因此,小心謹(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)系作者
  • 序言:七十年代末堰酿,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子张足,更是在濱河造成了極大的恐慌触创,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件为牍,死亡現(xiàn)場(chǎng)離奇詭異哼绑,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)碉咆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門抖韩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人疫铜,你說我怎么就攤上這事茂浮。” “怎么了壳咕?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵励稳,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我囱井,道長(zhǎng)驹尼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任庞呕,我火速辦了婚禮新翎,結(jié)果婚禮上程帕,老公的妹妹穿的比我還像新娘。我一直安慰自己地啰,他們只是感情好愁拭,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著亏吝,像睡著了一般岭埠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蔚鸥,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天惜论,我揣著相機(jī)與錄音,去河邊找鬼止喷。 笑死馆类,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的弹谁。 我是一名探鬼主播乾巧,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼预愤!你這毒婦竟也來了沟于?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤植康,失蹤者是張志新(化名)和其女友劉穎旷太,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體向图,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡泳秀,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了榄攀。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嗜傅。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖檩赢,靈堂內(nèi)的尸體忽然破棺而出吕嘀,到底是詐尸還是另有隱情,我是刑警寧澤贞瞒,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布偶房,位于F島的核電站,受9級(jí)特大地震影響军浆,放射性物質(zhì)發(fā)生泄漏棕洋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一乒融、第九天 我趴在偏房一處隱蔽的房頂上張望掰盘。 院中可真熱鬧摄悯,春花似錦、人聲如沸愧捕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽次绘。三九已至瘪阁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間邮偎,已是汗流浹背管跺。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留钢猛,地道東北人伙菜。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓轩缤,卻偏偏與公主長(zhǎng)得像命迈,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子火的,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

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

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