浅谈链式编程思想

一切都从一个需求开始

  • 项目需求: 设计一个计算器, 可以方便地进行加减乘除等计算

常规做法

  • 设计一个计算类CalculateMaker, 通过其属性result记录计算结果, 当我需要计算10-2+6+2-1时, 代码如下:
CalculateMaker *make = [[CalculateMaker alloc] init];
    make.result += 10;
    make.result -= 2;
    make.result += 6;
    make.result += 2;
    make.result -= 1;
NSLog(@"result = %zd", make.result);

非常规做法

  • 看到以上代码时, 很多人可能会很烦中间的计算, 光是5次计算就占用了5行代码, 有没有办法可以一行解决. 这就引出了今天的主题, 即链式编程. 我们直接看使用链式编程是如何进行计算的:
   NSUInteger result = [NSObject makeCalculator:^(CalculateMaker *make) {
                            make.add(10).minus(2).add(6).add(1).minus(5);
                        }];
   NSLog(@"result = %zd", result);
  • 先不管以上代码的实现原理, 单单是从代码结构上来讲, 理论上我们可以仅仅使用一行代码来实现无穷无尽的加减计算(尽管这行代码可能会很长, 但它也是一行). 关键是使用这种写法, 视觉上也更符合计算等式的逻辑.
  • 那么问题来了, 这段代码是如何做到等价于10-2+6+2-1? 如何做到连续使用点语法? 又是如何做到用(10), (2)这种格式来传值, 并最终得出我们想要的结果呢? 我们把疑问归结为以下三个来逐一分析.

疑问大全

1. CalculateMaker类是什么?
2. NSObject的类方法makeCalculator方法做了什么?
3. make.add(10).minus(2)是如何做到等价于10-2的, 并且连续使用点语法的?

[疑问一] CalculateMaker类是什么?

@interface CalculateMaker : NSObject

@property (nonatomic, assign) NSUInteger result;
- (CalculateMaker * (^)(int value))add;
- (CalculateMaker * (^)(int value))minus;

@end
  • 以上是CalculateMaker类的.h文件, 而根据代码我们不难得出结论, CalculateMaker只负责两件事:
    • 一是提供result属性记录计算结果
    • 二是提供add方法, minus方法进行加法计算和减法计算. (add和minus方法的实现稍后解释)

[疑问二] NSObject的类方法makeCalculator方法做了什么?

  • makeCalculator其实是一个NSObject的类拓展方法, 该方法提供一个block参数, 同时返回计算结果, 详细代码如下:
- (NSUInteger)makeCalculator:(void(^)(CalculateMaker *make))block{
    CalculateMaker *make = [[CalculateMaker alloc] init];   //1. 初始化一个CalculateMaker类
    block(make);               //2. 把CalculateMaker通过block传出去, 也等价于block所涉及的计算直接在这里执行
    return make.result;      //3. CalculateMaker执行完相关计算后, 把结果通过函数返回值传递出去
}

[疑问三] make.add(10).minus(2)是如何做到等价于10-2的, 并且连续使用点语法的?

(在这里我们仅以add为例进行解释)

- (CalculateMaker *(^)(int))add{
    return ^CalculateMaker * (int value) {
        self.result += value;
        return self;
    };
}
  • 以上是add方法的实现, 其本质即执行一段block.
  • 当代码执行make.add(10), CalculateMaker调用add方法执行这段block, 此时10作为 ^CalculateMaker * (int value)这个block的value参数传入, 传入后用于进行加法运算, 然后这段block又返回CalculateMaker自己.
  • 总结来讲, 通过执行make.add(10), CalculateMaker既实现了+10的运算并记录到result中, 而且还把自己作为返回值重新传递出来, 此时我们就可以拿到CalculateMaker, 并继续使用点语法调用minus继续进行计算.

后话

  • 眼尖的读者可能会发现, 这不就是Masonry框架的写法吗?!!! 没错, Masonry正是使用了链式编程来实现对NSLayoutConstraint的封装, 同样使用链式编程的还有远近驰名的Reative Cocoa. 对于常年写业务逻辑代码的工程师而言, 链式编程可能极少会用到, 但是了解链式编程其实不仅可以拓宽编程的认知水平, 而且也能进一步加深对block的理解, 最后如果想进一步了解Masonry实现细节以及链式编程的, 可以参阅以下两篇文章做更深层的学习.
    [1]https://www.jianshu.com/p/2d94a0e579d2
    [2]https://www.cnblogs.com/ludashi/archive/2016/07/11/5591572.html
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容