日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

对象作为参数示例java_功能Java示例 第6部分–用作参数

發(fā)布時(shí)間:2023/12/3 java 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 对象作为参数示例java_功能Java示例 第6部分–用作参数 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

對(duì)象作為參數(shù)示例java

這是稱(chēng)為“ Functional Java by Example”的系列文章的第6部分。

我在本系列的每個(gè)部分中開(kāi)發(fā)的示例是某種“提要處理程序”,用于處理文檔。 在前面的部分,我們?cè)噲D通過(guò)移動(dòng)盡可能多的副作用,如IO,該系統(tǒng)的外部,以使我們的純可能的功能。

現(xiàn)在,我們將一些抽象替換為函數(shù),以作為參數(shù)傳遞。

如果您是第一次來(lái),最好是從頭開(kāi)始閱讀。 它有助于了解我們從何處開(kāi)始以及如何在整個(gè)系列中繼續(xù)前進(jìn)。

這些都是這些部分:

  • 第1部分–從命令式到聲明式
  • 第2部分–講故事
  • 第3部分–不要使用異常來(lái)控制流程
  • 第4部分–首選不變性
  • 第5部分–將I / O移到外部
  • 第6部分–用作參數(shù)
  • 第7部分–將失敗也視為數(shù)據(jù)
  • 第8部分–更多純函數(shù)

我將在每篇文章發(fā)表時(shí)更新鏈接。 如果您通過(guò)內(nèi)容聯(lián)合組織來(lái)閱讀本文,請(qǐng)查看我博客上的原始文章。

每次代碼也被推送到這個(gè)GitHub項(xiàng)目 。

OO型協(xié)作者

還記得我們以前留下的東西嗎?

class FeedHandler {Webservice webserviceList<Doc> handle(List<Doc> changes) {changes.findAll { doc -> isImportant(doc) }.collect { doc ->createResource(doc).thenApply { resource ->setToProcessed(doc, resource)}.exceptionally { e ->setToFailed(doc, e)}.get()}}private CompletableFuture<Resource> createResource(doc) {webservice.create(doc)}private static boolean isImportant(doc) {doc.type == 'important'}private static Doc setToProcessed(doc, resource) {doc.copyWith(status: 'processed',apiId: resource.id)}private static Doc setToFailed(doc, e) {doc.copyWith(status: 'failed',error: e.message)}}

上面的提要處理程序需要一個(gè)“ Web服務(wù)”來(lái)完成其工作。

請(qǐng)看以下部分,其中使用WebService類(lèi)型的協(xié)作者來(lái)創(chuàng)建基于文檔的資源:

class FeedHandler {Webservice webserviceList<Doc> handle(List<Doc> changes) {changes.collect { doc ->createResource(doc)...}private CompletableFuture<Resource> createResource(doc) {webservice.create(doc)}}

請(qǐng)記住, 作為異常處理機(jī)制的一部分,我們將其包裝在CompletableFuture ,而不是直接返回資源。

如果我們想要WebService以外的其他資源來(lái)創(chuàng)建資源怎么辦?

好吧,這是同時(shí)變得棘手和容易的地方-OO風(fēng)格可能與FP風(fēng)格有些沖突。

您會(huì)看到, WebService是一個(gè)Java接口,定義如下:

interface Webservice {CompletableFuture<Resource> create(Doc doc) }

這遵循了Dependency Inversion Principle(DIP) ,它是Robert C. Martin提倡的SOLID設(shè)計(jì)原則的一部分,(其中包括):

抽象不應(yīng)依賴細(xì)節(jié)。 細(xì)節(jié)應(yīng)取決于抽象。

WebService已經(jīng)是任何類(lèi)型的Webservice 實(shí)現(xiàn)的抽象。 因此,系統(tǒng)可以具有此接口的多種實(shí)現(xiàn),例如REST實(shí)現(xiàn)和SOAP實(shí)現(xiàn):

class RestWebService implements Webservice {@OverrideCompletableFuture<Resource> create(Doc doc) {// do REST communication} } class SoapWebService implements Webservice {@OverrideCompletableFuture<Resource> create(Doc doc) {// do SOAP communication} }

提要處理程序不關(guān)心細(xì)節(jié) ,它只需要遵守WebService接口定義的協(xié)定的東西:有一個(gè)create方法可以接受Doc并返回CompletableFuture 。

FeedHandler類(lèi)具有一個(gè)webservice屬性,其中包含對(duì)WebService的引用。 任何OO開(kāi)發(fā)人員都可以識(shí)別這種樣式,因?yàn)樗浅J煜?#xff1a;所有協(xié)作者都存在于屬性中,這些屬性(通常)是在構(gòu)造過(guò)程中初始化的。

一旦構(gòu)造了FeedHandler ,就可以通過(guò)DI框架或普通的手工方法將傳遞的WebService實(shí)例傳遞給它-盡管可以使用構(gòu)造函數(shù)注入或?qū)傩宰⑷搿?

為了簡(jiǎn)潔起見(jiàn),我一直在代碼片段中省略了構(gòu)造函數(shù),但是正如您在測(cè)試用例中所看到的那樣, 我絕對(duì)使用Groovy為我生成的構(gòu)造函數(shù)傳遞所有依賴關(guān)系。

協(xié)作者FP風(fēng)格

好的,如果我們?cè)俅未魃螰unctional Hat,我們將需要重新審視將WebService傳遞到提要處理程序的方式。

該handle方法的簽名不提比其他任何東西:文件進(jìn)去 ,文件出來(lái) 。

class FeedHandler {...List<Doc> handle(List<Doc> changes) {...}}

我不能假定將返回相同的輸入 相同的輸出 -因?yàn)樵摲椒ò抵幸蕾囉谕獾臇|西:對(duì)WebService 。

好吧,也許我可以控制供稿處理程序的整個(gè)創(chuàng)建過(guò)程,包括WebService ,但是在方法調(diào)用之間可以更改對(duì)webservice引用,每次handle使用它時(shí)都會(huì)產(chǎn)生其他結(jié)果。 除非我將其設(shè)為不可變的,否則將阻止引用的更新。 我告訴過(guò)你可能會(huì)很棘手

是否可以像上一期中使用isImportant , setToProcessed和setToFailed方法一樣使純正的 handle ?

在這種情況下,我們必須將WebService作為參數(shù)傳遞,就像傳遞文檔列表一樣。

我們改變

class FeedHandler {Webservice webserviceList<Doc> handle(List<Doc> changes) {...}}

進(jìn)入

class FeedHandler {List<Doc> handle(List<Doc> changes, Webservice webservice) {...}}

在每次調(diào)用handle我們都會(huì)傳遞它需要的所有內(nèi)容:需要處理的文檔和需要使用的Web服務(wù)。

由于此方法不再依賴于FeedHandler類(lèi)中的任何屬性,因此我們現(xiàn)在可以使其變?yōu)閟tatic -將其升級(jí)為類(lèi)級(jí)方法。

高階函數(shù)

實(shí)際上,我們的handle方法剛剛變成了所謂的“高階函數(shù)”,即接受一個(gè)函數(shù)或返回一個(gè)函數(shù)的函數(shù)。

因此,回到開(kāi)始時(shí)我提出的一個(gè)問(wèn)題: 如果我們想要WebService以外的其他東西來(lái)創(chuàng)建資源該怎么辦?

它甚至不應(yīng)該是Web服務(wù)嗎? 也許我們完全想吃香蕉,一只猴子為我們創(chuàng)造資源?

class Monkey implements Webservice {@OverrideCompletableFuture<Resource> create(Doc doc) {// go bananas! But do create resources plz} }

看起來(lái)很奇怪,不是嗎? 對(duì)于抽象提要處理程序的需要, WebService接口太具體了。 任何創(chuàng)造資源的東西都會(huì)起作用,不是嗎?

更好的名稱(chēng)是“ ResourceCreator” ,因此只需重命名接口即可。

舊:

interface Webservice {CompletableFuture<Resource> create(Doc doc) }

新:

interface ResourceCreator {CompletableFuture<Resource> create(Doc doc) }

具有create方法的ResourceCreator接口; 多么合身! 現(xiàn)在任何東西都可以實(shí)現(xiàn)此接口,并且提要處理程序甚至不在乎它是Web服務(wù),猴子還是霍比特人。

新方法簽名:

class FeedHandler {List<Doc> handle(List<Doc> changes, ResourceCreator creator) {...}}

完美的抽象!

功能抽象

在Java中,我們將只有一種抽象方法的接口稱(chēng)為功能接口 。 我們的ResourceCreator符合此描述; 它具有單個(gè)抽象方法create 。

Java的java.util.function程序包具有許多這些功能接口,并且每個(gè)功能接口都有一個(gè)已定義的用途:

  • Consumer表示一個(gè)接受參數(shù)且不返回任何內(nèi)容的函數(shù)
  • Supplier表示不接受任何參數(shù)的函數(shù),僅返回結(jié)果
  • Function表示接受一個(gè)參數(shù)并返回結(jié)果的函數(shù)
  • …和更多

這意味著,我們不需要每次都需要一個(gè)函數(shù)“接受一個(gè)參數(shù)并返回結(jié)果”時(shí)就定義一個(gè)特定的接口,例如ResourceCreator - Function已經(jīng)是一個(gè)我們可以利用的接口!

這就是Java 8中的Function (簡(jiǎn)體)的樣子:

interface Function<T,R> {R apply(T t); }

這就是ResourceCreator現(xiàn)在的樣子:

interface ResourceCreator {CompletableFuture<Resource> create(Doc doc) }

您會(huì)看到,如果滿足以下條件,我們可以用Function完全替代ResourceCreator :

  • 用Doc代替R型
  • 用T型替代CompletableFuture
  • 替代調(diào)用create由該方法apply

我們可以完全刪除ResourceCreator界面!

新方法簽名將變?yōu)?#xff1a;

class FeedHandler {List<Doc> handle(List<Doc> changes,Function<Doc, CompletableFuture<Resource>> creator) {...}}

我們?nèi)〉昧耸裁闯删?#xff1f;

  • 我們現(xiàn)在可以傳遞任何要handle 函數(shù) ,該函數(shù)需要一個(gè)Doc并產(chǎn)生一個(gè)CompletableFuture —這就是feed處理程序正常工作所需的全部。
  • 正如您現(xiàn)在可能已經(jīng)注意到的,函數(shù)編程處理了很多函數(shù) 。 一個(gè)函數(shù)可以采用另一個(gè)函數(shù),也可以返回一個(gè)函數(shù)。
  • 從Java 8開(kāi)始,我們已經(jīng)準(zhǔn)備好了很多功能接口。 每個(gè)開(kāi)發(fā)人員都可以以標(biāo)準(zhǔn)化的方式與他們合作,因此最好查看它們是否適合您的用例和API,并盡可能重用它們。 他們每個(gè)人都有泛型類(lèi)型(如T和R可以由你來(lái)表明在發(fā)生什么,什么來(lái)的函數(shù)的輸出 )。

現(xiàn)在,完整的代碼如下所示:

class FeedHandler {List<Doc> handle(List<Doc> changes,Function<Doc, CompletableFuture<Resource>> creator) {changes.findAll { doc -> isImportant(doc) }.collect { doc ->creator.apply(doc).thenApply { resource ->setToProcessed(doc, resource)}.exceptionally { e ->setToFailed(doc, e)}.get()}}private static boolean isImportant(doc) {doc.type == 'important'}private static Doc setToProcessed(doc, resource) {doc.copyWith(status: 'processed',apiId: resource.id)}private static Doc setToFailed(doc, e) {doc.copyWith(status: 'failed',error: e.message)}}

現(xiàn)在就這樣! 下次,我們將處理故障數(shù)據(jù)。

如果您有任何意見(jiàn)或建議,我很想聽(tīng)聽(tīng)他們的意見(jiàn)!

翻譯自: https://www.javacodegeeks.com/2018/12/functional-java-functions-parameters.html

對(duì)象作為參數(shù)示例java

總結(jié)

以上是生活随笔為你收集整理的对象作为参数示例java_功能Java示例 第6部分–用作参数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。