本文翻译自: Composition in Flutter & Dart

在 Flutter & Dart 中运用组合创立模块化应用程序。

函数式编程:Flutter&Dart中的组合

什么是组合?

在dictionary.com 中 composition 的界说为:将部分或者元素组合成一个整体的行为。简略说,组合就像堆乐高积木,咱们能够将积木组合成一个结构。

在 FP 中,咱们界说了一个简略的通用函数,该函数能够经过组合构成一个杂乱的函数,一个函数的输出是别的一个函数的输入,依此类推。输入从一个函数传递到别的一个函数最终回来成果。因而,组合能够认为是数据活动的管道。

组合的数字符号是 f.g。 f(g(x))它从里向外履行。

  1. 首要 x 初始化。
  2. 将 x 作为参数传递给 g,g(x)被初始化。
  3. g(x)被核算并将成果传递给 f 函数,最终 f(g(x))被核算。

在 Dart 中,组合函数能够表明如下:

函数式编程:Flutter&Dart中的组合

Compose 是个高阶函数,它接纳两个函数并回来一个可接纳输入的函数。 组合的履行次序是从右到左,因而g先履行,然后再履行f

函数式编程:Flutter&Dart中的组合

如上图创立了函数shout,它由两个较小的功用函数toUpperexclaim组成。

第 4 行,组合这两个函数创立shout函数.

第 8 行运用了包Dartz中供给的函数composeF

Flutter 中如何运用组合?

Flutter 框架是展示组合功用的最佳示例之一,咱们组合控件来进行UI设计。比方你想设置 padding,能够用Padding来组合,你想设置一些装修,能够用DecoratedBox来进行组合等等。

Flutter 大量运用了组合。控件树便是咱们用组合处理 UI 的成果.控件就像乐高积木,小的通用控件能够被组合成杂乱的控件或者用户界面。比方,Container就包含了几个控件,如Padding,DecoratedBox,Align,LimitedBox等。

这里偏重介绍组合在实践中应用让读者更深刻理解组合概念,本质上来说Flutter中的控件组合与函数式编程中的组合仍是有点差异,两则编程范式不相同,Flutter 控件间组合偏重于面向对象编程,对象是根本单元,控件都是对象;而函数的组合偏重于函数式编程,无状态函数是根本单元。

组合与管道

与 compose 类似,这里介绍别的一个概念:管道。两者差异在于组合履行次序是从右到左,而管道履行次序是从左至右

这个差异尤为重要,不要忽视,它间接影响到代码可读性。中国人的阅读习惯是从左到右的,假如你是阿拉伯人能够疏忽我说的,哈哈!

函数式编程:Flutter&Dart中的组合

在第 14 行,运用了 compose,它的履行次序是从右至左,函数 g 首要履行,成果传递给 f 。

在第 17 行,运用了管道,它的履行次序是从左至右,函数 f 先履行,成果传递给 g 。

假如运用 compose,输入 10 先履行increment 增加到 11 然后乘以 2,因而履行成果是 22.

假如运用管道,输入 10 先履行doubler乘以 2 变成 20,然后履行increment递增到 21 并回来。

Example 示例

结合所学的概念,咱们能够创立几个函数,完成字符串的改换。

函数式编程:Flutter&Dart中的组合

咱们需求能够将上述用例相互转化的函数。

就像乐高游戏相同,首要需求乐高积木,在这个例子中咱们需求具有一些根底功用的函数。

函数式编程:Flutter&Dart中的组合

之前界说的 Compose 函数只接纳两个函数作为参数,现在界说一个能够接纳 n 个参数的函数。

函数式编程:Flutter&Dart中的组合

咱们创立了如上代码,接下来能够用它来完成更有意思的函数,这些函数将被运用,经过Github 库房查找更多信息。

Snake case to Pascal case

接下来将从 Snake case 转化成 camel,pascal 和 kebab cases。

函数式编程:Flutter&Dart中的组合

const _pascalCase = ‘LoremIpsumDolorSitAmet’;

const _snakeCase = ‘lorem_ipsum_dolor_sit_amet’;

在第 5 行中,界说了_snakeToPascal 函数,它接纳一个参数并回来成果。_snakeToPascal由三个小函数组合而成:splitWithUnderscore,capitalizeWordsjoinWithoutSpace 。将“lorem_ipsum_dolor_sit_amet”作为参数传入函数中,compose 是从右至左的履行次序。因而:

  1. 首要输入字符串先传给splitWithUnderscore,该函数将输入拆分成 [“lorem”, “ipsum”, “dolor”, “sit”, “amet”]

  2. splitWithUnderscore的回来值是一个数组,它将被传递给第二个函数,即capitalizeWords将每个元素的首字母转化成大写并回来列表 [“Lorem”, “Ipsum”, “Dolor”, “Sit”, “Amet”]

  3. capitalizeWords的回来成果将被传递给 joinWithoutSpace,该函数将元素连接在一起并回来成果 “LoremIpsumDolorSitAmet”

还记得咱们之前讲的么? 咱们经过组合为数据界说一个管道,像上面这样。数据流经过这些管道并回来成果,花些时刻来构建一些根底功用函数,组合他们生成更有意义的函数就变得很简单了。

Snake case to Camel case

const _snakeCase = ‘lorem_ipsum_dolor_sit_amet’;

const _camelCase = ‘loremIpsumDolorSitAmet’;

第 15 行_snakeToCamel非常简略,第一个与最终一个函数都是与上面转化都是相同的:splitWithUnderscorejoinWithoutSpace,将中心函数从capitalizeWords 修改为 capitalizeTail,咱们的功用就完成了。原因是 camelCase 的情况下不需求将第一个单词大写。capitalizeTailcapitalizeWords类似,但是它疏忽了第一个单词处理,匹配了咱们的用例。

Snake case to Kebab case

Snake case 转化成 kebab case 更简略.只需求组合两个函数 (splitWithUnderscore&joinWithHyphen),就能够完成任务。

Camel case to other cases

函数式编程:Flutter&Dart中的组合

Kebab case to other cases

函数式编程:Flutter&Dart中的组合

Pascal case to other cases

函数式编程:Flutter&Dart中的组合

想法

我喜爱将组合视为一种分治技能。组合的首要长处是得到高复用和可定制功用。

文中源码地址 GitHub

太棒了!鼓舞自己坚持到底。我期望我为你投入的时刻增加了一些价值。

假如觉得文章对你有协助,点赞、收藏、重视、评论,一键四连支撑,你的支撑便是我创造最大的动力。

❤️ 本文原创听蝉 公众号:编程黑板报 欢迎重视原创技能文章第一时刻推送❤️