java 函数式编程 示例_功能Java示例 第1部分–从命令式到声明式
java 函數(shù)式編程 示例
功能編程(FP)的目的是避免重新分配變量,避免可變的數(shù)據(jù)結(jié)構(gòu),避免狀態(tài)并全程支持函數(shù)。 如果將功能性技術(shù)應(yīng)用于日常Java代碼,我們可以從FP中學(xué)到什么?
在這個名為“ Functional Java by Example”的系列文章中,我將分8步重構(gòu)現(xiàn)有代碼,以查看是否可以用Java達(dá)到Functional Nirvana 。
我對Haskell或F#等“真正的”功能語言沒有太多經(jīng)驗,但是我希望在每篇文章中以示例方式演示將這些實踐中的一些應(yīng)用于每天的Java代碼意味著什么。
希望最后您獲得了一些見識,并且知道選擇一些有益于您自己的代碼庫的技術(shù)。
這些都是這些部分:
- 第1部分–從命令式到聲明式
- 第2部分–命名事物
- 第3部分–不要使用異常來控制流程
- 第4部分–首選不變性
- 第5部分–將I / O移到外部
- 第6部分–用作參數(shù)
- 第7部分–將失敗也視為數(shù)據(jù)
- 第8部分–更多純函數(shù)
我將在每篇文章發(fā)表時更新鏈接。 如果您通過內(nèi)容聯(lián)合組織來閱讀本文,請查看我博客上的原始文章。
每次代碼也被推送到這個GitHub項目 。
免責(zé)聲明:代碼是用Apache的Groovy中 ,主要是為簡潔,所以我不必鍵入的東西(你知道:打字),其中不要緊的例子。 第二,這門語言只是讓我開心。
為什么要關(guān)心函數(shù)式編程(FP)?
如果您不是在時髦的實時流數(shù)據(jù)事件處理框架上執(zhí)行Haskell,F#或Scala,則最好打包。 這些天,甚至JavaScript的人都在圍繞您的方法旋轉(zhuǎn)函數(shù)-這種語言已經(jīng)存在了一段時間。
那里有很多文章和視頻,使您相信,如果這些天沒有跳上功能性潮流,那么您會被舊的OOP束縛所拋棄,坦率地說,它們會在幾年內(nèi)過時。
好吧,我在這里告訴您這不是完全正確的,但是FP 確實有一些前提,例如可讀性,可測試性和可維護(hù)性 ,我們也在我們的(企業(yè))Java代碼中力求實現(xiàn)的值正確嗎?
在閱讀本文時,多年以來,您可能已經(jīng)對FP是前進(jìn)還是后退或2017-2018年年期失敗表達(dá)了相同的直率觀點,您只是愿意接受新想法
通過學(xué)習(xí)FP,您可以提高每種語言的技能。
確定自己是什么,你可以從中學(xué)到如何自己編程可以從中受益。
如果您能勝任這項任務(wù),那么讓我們從...開始
現(xiàn)有的一些代碼
關(guān)于示例代碼的一句話:為這樣的博客提供人為的示例是非常棘手的:它應(yīng)該足夠容易吸引廣泛的受眾,應(yīng)該足夠簡單,無需太多上下文就可以理解,但仍然足夠有趣以至于導(dǎo)致理想的學(xué)習(xí)效果。
展望未來,本系列的每一期將以前一期為基礎(chǔ)。 下面是我們將作為起點的代碼。
因此,戴上眼鏡,看看您是否熟悉下面的編碼樣式。
class FeedHandler {Webservice webserviceDocumentDb documentDbvoid handle(List<Doc> changes) {for (int i = 0; i < changes.size(); i++) {def doc = changes[i]if (doc.type == 'important') {try {def resource = webservice.create(doc)doc.apiId = resource.iddoc.status = 'processed'} catch (e) {doc.status = 'failed'doc.error = e.message}documentDb.update(doc)}}} }- 這是某種FeedHandler 。
- 它有兩個屬性,一些Webservice類和DocumentDb類。
- 有一個handle方法可以對Doc對象列表進(jìn)行處理。 文件?
嘗試弄清楚這里發(fā)生了什么
..
..
..
做完了嗎
讀這樣的東西有時會使您感到自己像一個解析器。
掃描類名( FeedHandler? )和一個方法( void handle )可以使您感到有些FeedHandler? ,從而使您感到FeedHandler? 。
但是,弄清楚在handle方法中確切“處理”了什么要困難得多。
- 那里有一個for-loop -但是到底是在迭代什么? 多少次?
- 調(diào)用此變量webservice ,返回稱為resource 。
- 如果webservice成功返回,則正在迭代的doc (文檔?)將更新為狀態(tài)。
- 似乎webservice還可以拋出一個Exception ,它被捕獲和文檔與其他狀態(tài)更新。
- 最終,該文檔被此documentDb實例“更新”。 看起來像一個數(shù)據(jù)庫。
- 等等,這僅適用于“重要”文檔 -在進(jìn)行上述所有操作之前,首先檢查doc.type 。
也許,您聽說過以下短語:
讀取的代碼多于編寫的代碼。
看看這塊美麗:
for (int i = 0; i < changes.size(); i++) {上面的代碼以命令式的方式編寫,這意味著操作狀態(tài)和行為的具體語句被明確地寫出。
- 用零初始化一個int i
- 當(dāng)int i小于changes列表的大小時循環(huán)
- 每次迭代以1遞增int i
用這種命令式 (過程)編碼風(fēng)格(大多數(shù)主流語言,包括Java,C ++,C#等面向?qū)ο缶幊?#xff08;OOP)語言,都被設(shè)計為主要支持),開發(fā)人員編寫了計算機(jī)所需的確切語句。執(zhí)行以完成特定任務(wù)。
一些非常命令性 (過程性)代碼的信號:
該代碼明確地側(cè)重于“如何”,這使“什么”難以確定。
專注于什么
就像本文的標(biāo)題已經(jīng)不一樣,我們的第一步是從命令式的編碼和重構(gòu)方法轉(zhuǎn)變?yōu)楦呗暶餍缘臉邮?FP是一種形式。
這個循環(huán)最困擾我。
這是代碼的新版本。
class FeedHandler {Webservice webserviceDocumentDb documentDbvoid handle(List<Doc> changes) {// for (int i = 0; i < changes.size(); i++) {// def doc = changes[i]changes.findAll { doc -> doc.type == 'important' }.each { doc ->try {def resource = webservice.create(doc)doc.apiId = resource.iddoc.status = 'processed'} catch (e) {doc.status = 'failed'doc.error = e.message}documentDb.update(doc)}} }有什么變化?
- if (doc.type == 'important')部分已替換為findAll { doc -> doc.type == 'important' } if (doc.type == 'important') findAll { doc -> doc.type == 'important' } findAll { doc -> doc.type == 'important' }再次涉及文檔集合本身- 意思是“查找所有重要的文檔,并僅返回那些重要文檔的新集合”
- 強(qiáng)制性的for-loop (帶有中間的i變量)已由文檔集合本身上的聲明性的each方法所取代- 表示“為列表中的每個文檔執(zhí)行一段代碼,我不在乎您如何執(zhí)行” &#55357;&#56898;
不用擔(dān)心each和findAll :這些方法是Groovy所添加的,我將它們與Java在同一代碼庫中愉快地一起使用,添加到了任何Set(例如Set,List,Map)中。 Vanilla Java 8具有等效的機(jī)制,例如forEach可以更聲明性地迭代集合。
導(dǎo)致可讀軟件的原因是:
描述“什么”而不是“如何” 。
如果我以更加實用的方式編寫代碼,就可以輕松地看到發(fā)生了什么,這可以節(jié)省我的時間 (因為是的,我90%的時間都在讀取代碼而不是編寫代碼),并且這樣編寫代碼不容易出錯 ,因為更少的行會減少隱藏錯誤的機(jī)會。
現(xiàn)在就這樣
在第2部分中,我們將正確命名事物 ,為更多功能的編程鋪平道路,例如在本系列的后續(xù)版本中,“ Either”或“ Try”。
翻譯自: https://www.javacodegeeks.com/2017/11/functional-java-example-part-1-imperative-declarative.html
java 函數(shù)式編程 示例
總結(jié)
以上是生活随笔為你收集整理的java 函数式编程 示例_功能Java示例 第1部分–从命令式到声明式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 威霆改装备案流程(威霆改装备案)
- 下一篇: 并发查询parallel_惯用并发:fl