本文翻譯自: Composition in Flutter & Dart
在 Flutter & Dart 中使用組合創建模塊化應用程式,

什么是組合?
在dictionary.com 中 composition 的定義為:將部分或者元素組合成一個整體的行為,簡單說,組合就像堆樂高積木,我們可以將積木組合成一個結構,
在 FP 中,我們定義了一個簡單的通用函式,該函式可以通過組合構成一個復雜的函式,一個函式的輸出是另外一個函式的輸入,依此類推,輸入從一個函式傳遞到另外一個函式最后回傳結果,因此,組合可以認為是資料流動的管道,
組合的數字符號是 f.g, f(g(x))它從里向外執行,
- 首先 x 初始化,
- 將 x 作為引數傳遞給 g,g(x)被初始化,
- g(x)被計算并將結果傳遞給 f 函式,最后 f(g(x))被計算,
在 Dart 中,組合函式可以表示如下:

Compose 是個高階函式,它接收兩個函式并回傳一個可接收輸入的函式, 組合的執行順序是從右到左,因此g先執行,然后再執行f,

如上圖創建了函式shout,它由兩個較小的功能函式toUpper和exclaim組成,
第 4 行,組合這兩個函式創建shout函式.
第 8 行使用了包Dartz中提供的函式composeF,
Flutter 中如何使用組合?
Flutter 框架是展示組合功能的最佳示例之一,我們組合控制元件來進行UI設計,比如你想設定 padding,可以用Padding來組合,你想設定一些裝飾,可以用DecoratedBox來進行組合等等,
Flutter 大量使用了組合,控制元件樹就是我們用組合處理 UI 的結果.控制元件就像樂高積木,小的通用控制元件可以被組合成復雜的控制元件或者用戶界面,比如,Container就包含了幾個控制元件,如Padding, DecoratedBox, Align, LimitedBox等,
這里偏重介紹組合在實踐中應用讓讀者更深刻理解組合概念,本質上來說Flutter中的控制元件組合與函式式編程中的組合還是有點區別,兩則編程范式不一樣,Flutter 控制元件間組合偏重于面向物件編程,物件是基本單元,控制元件都是物件;而函式的組合偏重于函式式編程,無狀態函式是基本單元,
組合與管道
與 compose 類似,這里介紹另外一個概念:管道,兩者區別在于組合執行順序是從右到左,而管道執行順序是從左至右,
這個區別尤為重要,不要忽視,它間接影響到代碼可讀性,中國人的閱讀習慣是從左到右的,如果你是阿拉伯人可以忽略我說的,哈哈!

在第 14 行,使用了 compose,它的執行順序是從右至左,函式 g 首先執行,結果傳遞給 f ,
在第 17 行,使用了管道,它的執行順序是從左至右,函式 f 先執行,結果傳遞給 g ,
如果使用 compose,輸入 10 先執行increment 增加到 11 然后乘以 2,因此執行結果是 22.
如果使用管道,輸入 10 先執行doubler乘以 2 變成 20,然后執行increment遞增到 21 并回傳,
Example 示例
結合所學的概念,我們可以創建幾個函式,實作字串的變換,

我們需要可以將上述用例相互轉換的函式,
就像樂高游戲一樣,首先需要樂高積木,在這個例子中我們需要具有一些基礎功能的函式,

之前定義的 Compose 函式只接收兩個函式作為引數,現在定義一個可以接收 n 個引數的函式,

我們創建了如上代碼,接下來可以用它來實作更有意思的函式,這些函式將被使用,通過Github 倉庫查找更多資訊,
Snake case to Pascal case
接下來將從 Snake case 轉換成 camel,pascal 和 kebab cases,

const _pascalCase = 'LoremIpsumDolorSitAmet';
const _snakeCase = 'lorem_ipsum_dolor_sit_amet';
在第 5 行中,定義了_snakeToPascal 函式,它接收一個引數并回傳結果,_snakeToPascal由三個小函陣列合而成:splitWithUnderscore, capitalizeWords和 joinWithoutSpace ,將“lorem_ipsum_dolor_sit_amet”作為引數傳入函式中,compose 是從右至左的執行順序,因此:
-
首先輸入字串先傳給
splitWithUnderscore,該函式將輸入拆分成 [“lorem”, “ipsum”, “dolor”, “sit”, “amet”], -
splitWithUnderscore的回傳值是一個陣列,它將被傳遞給第二個函式,即capitalizeWords將每個元素的首字母轉換成大寫并回傳串列 [“Lorem”, “Ipsum”, “Dolor”, “Sit”, “Amet”], -
capitalizeWords的回傳結果將被傳遞給joinWithoutSpace,該函式將元素連接在一起并回傳結果 “LoremIpsumDolorSitAmet”
還記得我們之前講的么? 我們通過組合為資料定義一個管道,像上面這樣,資料流通過這些管道并回傳結果,花些時間來構建一些基礎功能函式,組合他們生成更有意義的函式就變得很容易了,
Snake case to Camel case
const _snakeCase = 'lorem_ipsum_dolor_sit_amet';
const _camelCase = 'loremIpsumDolorSitAmet';
第 15 行_snakeToCamel非常簡單,第一個與最后一個函式都是與上面轉換都是相同的:splitWithUnderscore 和 joinWithoutSpace,將中間函式從capitalizeWords 修改為 capitalizeTail,我們的功能就實作了,原因是 camelCase 的情況下不需要將第一個單詞大寫,capitalizeTail與capitalizeWords類似,但是它忽略了第一個單詞處理,匹配了我們的用例,
Snake case to Kebab case
Snake case 轉換成 kebab case 更簡單.只需要組合兩個函式 (splitWithUnderscore & joinWithHyphen),就可以完成任務,
Camel case to other cases

Kebab case to other cases

Pascal case to other cases

想法
我喜歡將組合視為一種分治技術,組合的主要優點是得到高復用和可定制功能,
文中原始碼地址 GitHub
太棒了!鼓勵自己堅持到底,我希望我為你投入的時間增加了一些價值,
如果覺得文章對你有幫助,點贊、收藏、關注、評論,一鍵四連支持,你的支持就是我創作最大的動力,
?? 本文原創聽蟬 公眾號:碼里特別有禪 歡迎關注原創技術文章第一時間推送 ??
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/543950.html
標籤:其他
上一篇:無線電發射設備管理規定
下一篇:Opengl ES之踩坑記
