中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何從Moco解析程序庫設計

發布時間:2021-10-29 17:23:33 來源:億速云 閱讀:175 作者:柒染 欄目:編程語言

如何從Moco解析程序庫設計,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

Moco在程序庫設計包括兩個方面,如何設置服務器和如何讓服務器運行起來。

先說簡單的,如何讓服務器運行。最簡單的選擇是讓用戶自己啟動服務器,然后,在測試結束之后關閉服務器。這么一來,每個測試都大概會是這樣:

public void shouldWork() {    ... setup server ...    try {      server.start();      ... your test here ...     } finally {      server.stop();    }  }

作為一個框架,留給客戶使用的接口一定簡單,把實現細節封裝在框架以內。如果每個測試都這么寫,用戶很快就會罵娘了。現在的Moco的做法是使用了running方法,把Server啟停的細節封裝了起來。

running(server, new Runnable() {    @Override   public void run() throws Exception {      assertThat(helper.get(root()), is("foo"));    }  });

我知道你不喜歡匿名內部類,我也不喜歡,但是,這是Java的局限。等到Java 8駕臨,相信一切會有所改觀。

設置服務器,也就是在什么樣的請求,給什么樣的應答。Moco有一個很關鍵的起點,那便是DSL,要知道,之前的一段時間我剛剛完成了《領域特定語言》的翻譯。于是,API的可讀性成了一件非常重要的事。

說起來很簡單,但是,要知道匹配請求的條件有很多,而且還可能任意組合。如果這些條件是彼此獨立的(“或”),我可以用變參來解決,但有時,這些條件是相關的(“與”),那該怎么辦呢?拜函數式編程思路所賜,我想到了函數組合的方式。

我知道,Java沒有一等公民的函數,但是,Java里有一等公民的對象,我們可以用對象模擬函數,事實上,這也是很多面向對象程序設計語言解決函數組合的一種方式,而這種對象稱為函數對象,也叫functor。

把需要的條件封裝成一個個函數對象,然后通過幾個簡單的運算符就可以將它們組合起來。目前Moco里提供了and和or兩個運算符用于組合。

server.request(and(by(uri("/foo")), by(method("put")))).response("bar");  server.request(or(by("foo"), by(uri("/foo")))).response("bar");

隨著面向對象思路的普及,函數組合的寫法會越來越普遍的,它會成為程序員工具箱中的必備品。

DSL是一個重要的考量,所以,這里沒有直接new對象,而是用函數(比如uri、method)做了一層封裝。或許你會說,那為了可讀性,我可以把類名設計成一個可讀的樣子,但new一個對象的問題在哪呢?就在new上。一方面,new是為了創建一個對象,這是實現細節,與我們要表達的內容不在一個層次,另一方面,你會發現多個new會讓這句話顯得不連貫。這句話?是的,我們的寫法就像是用一句話聲明一個東西一樣,而我們期望自己講的內容有一定的連貫性,而這才是DSL。

一旦設計成DSL,單個函數的文檔也就失去了意義,更重要的是一個用法的文檔。所以,在Moco里,我寫了文檔,卻沒有寫JavaDoc。

在Moco里,請求和應答里可能有同樣的東西,比如file,而request和response的參數類型是不一樣的。如果file能夠返回不同類型是***的,可惜在Java里面,我們不可能根據返回類型做重載。一種解決方案是為request和response分別設計一個函數,比如requestFile和responseFile,但顯然,這種做法會把同樣的邏輯分散到兩個類實現里,而且這樣需要共享的東西不只是file,還有其它一些東西。

在計算機問題里,加上一個中間層永遠是一個重要的解決方案。這也是by的目的所在。這樣一來,這些共享的東西就可以做成一個抽象(Resource),對請求來說,只要有一個by,就可以適配成Matcher。

在Moco設計中,還涉及到了一個框架設計中很重要的點:類型。Java是靜態類型程序設計語言,利用好類型,就可以在編譯期把錯誤報出來,而不會留到運行時,fail fast是很重要的一個程序設計實踐。

Moco目前支持一些Content Type檢測。如果把這個Content Type放到Resource里面,你會發現不是所有Resource都需要這個,比如method,我們當然可以在Resource接口里支持Content Type,在不需要的地方拋出異常。

在Moco里,我的做法是引入了一個ContentResource,支持Content Type,它繼承于Resource,這樣依賴,需要Content Type的接口(比如content),直接支持ContentResource,而其它部分繼續支持Resource,這樣,如果一不小心用錯的話,編譯就會報錯。

再有一點是關于Publish接口,在Moco的實現里有一個Setting,還有一個BaseSetting,如果觀察實現,在設置Request會創建出一個BaseSetting,但其返回的接口是Setting。這么做的一個原因是,因為Setting出現在用戶可以使用的接口上,而BaseSetting是留給內部實現的,它提供了一些用于內部實現的方法,而用戶是不應該使用這些方法的,所以,將二者做了一個分離,這樣一來,保證了用戶不會誤操作。同樣處理的還有HttpServer和ActualHttpServer。

小結一番,簡化用戶接口,設計DSL,利用好類型,區分Publish接口。

看完上述內容,你們掌握如何從Moco解析程序庫設計的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

高雄县| 桃江县| 礼泉县| 聊城市| 镇宁| 饶阳县| 通江县| 保德县| 海安县| 罗源县| 连云港市| 青州市| 滦平县| 宁化县| 太和县| 兴业县| 龙里县| 乐昌市| 任丘市| 田阳县| 肥东县| 寿阳县| 通城县| 平阳县| 晴隆县| 葵青区| 沛县| 永宁县| 阿克苏市| 滕州市| 仁化县| 都匀市| 华阴市| 盐亭县| 乌拉特前旗| 修武县| 渑池县| 虞城县| 商丘市| 泰州市| 历史|