异步调用和多线程的架构设计

继续分析架构设计,http call是ios程序常用的与服务器通信和同步数据的方式,框架层给我们提供了简单的同步和异步方法,今天就想分析分析,同步和异步。

首先不考虑同步和异步的内部实现,但就两种方式的特性,两种方法都能完成功能,可是具体到架构的时候我们用哪一种呢??

优先考虑异步方法,为什么,以为异步方法的逻辑能更好的支持低耦合高内聚的设计模式思想,但是如果只是以优先使用异步方法为前提进行程序设计,就会发现遇到很多非常痛苦的问题,好些时候我们在http请求时候要记录context,好在回调的时候接这context继续执行逻辑,这时候我们就想这不明显应该用同步方法么,用异步干什么?

So,其实问题出在这是用同步调用的思维设计异步方法程序,当然别扭了,为了context可能需要一个全局变量,甚至把context传如Api再让Api回传,这两种方式显然都不好,所以要用异步的思维设计异步程序。

最近又有一些想写的了,上回其实已经想到用异步的思维设计异步程序,这回就说说程序设计到底改怎么写。

首先最常见的程序逻辑肯定是顺序执行吧,为什么呢,因为这符合自然规律,凡事当然有先后,即便是并发的也依然会有先后的次序,所以写代码很容易就按照执行先后次序写code。

举个不那么贴切的例子,执行一个任务,把汽车从熄火锁闭状态调整到匀速前进状态,马上就可以简单抽像出几个步骤

1. 开锁

2. 拧钥匙发动

3. 挂到前进挡

4. 踩油门

5. 调整方向

6. 看仪表盘保持速度

7. 结束

好,看起来很顺畅按照这个顺序写code不就好了么,可是这和同步异步多线程有什么关系呢?关系就在具体的逻辑实现和更加底层的功能实现上。

1. 程序入口肯定从开锁起,开锁比较快,基本上可以做到马上返回结果,true or false一个分支接着写逻辑就好,同步操作没有什么异议,不过放在子线程还是主线程呢?

主线程一般都是用于交互的,那么开锁肯定是用户发起的操作,开锁的逻辑简单那么可以直接写在主线程马上返回即可。

2. 拧钥匙发动,这又是一个貌似简单的过程,但是这次就要复杂点了,从点火到发动机开始工作肯定是一个复杂的逻辑过程,而且车况不好可能还得多试几次,不过因为时间短,继续写同步方法在主线程,因为发动不起来后面就不能执行,这样也没有问题

3. 挂档,这一步相当于发指令给变速箱,变速箱做出响应,进入前进模式,但是档位的变化需要一定的时间去完成所以考虑做成异步操作

4. 踩油门,又是一个指令,依然需要时间,异步

5. 调整方向,立竿见影同步主线程

6. 看仪表盘,观察者模式,达到一定速度开始收油门响应,保持速度

7. 保持状态量,让步骤6的逻辑保持执行

ok,写完了,这就是常见的写法,功能实现逻辑完整没有什么问题,run一起,估计也差不到哪去,但是写的时候会发现好多别扭的地方,而且最后的效果也未必够好,用户不满意,咋办,作为程序还要考虑优化的问题,因为这些步骤可能以后还会加新东西。

a. 3,4是两个异步操作,顺序写好的代码到这里就断掉了,因为不能顺序的执行,为什么呢?因为虽然写成了异步操作但是还是需要等待它执行完成才能走5,6步骤的,这样就变成了挖坑了,明明需要同步却不得不因为异步操作破坏掉通顺的代码逻辑, 到这里就得好好想想了,这好别扭啊为什么会这样呢,现实成活中很简单的事情为什么必须用异步来做呢,因为程序就不是现实,程序是基于计算机的原理来实现的,一个cpu,就一个cpu,运算都靠一个cpu所以程序是通过计算机原理去模拟现实世界的逻辑关系,关键就在模拟,它是让运行看起来和客观现实一样,底下走的必然是围绕cpu进行的甚至完全不同的过程。

用户交互优先级最高,不然就是死机了,所以甭管你需要做什么样的操作,让用户感觉好才行,所以一切交互都优先在主线程,遇到耗时需要等待的时候怎么办,UI得接着刷新,逻辑上完全同步的行为就busyindicator,逻辑上可以让用户先干别的就得多线程伺候着,这才像个样子,但是程序写成这样你就只能忍着了,没辙,为什么呢,因为这还是顺序编程,根本不是面向对象,你没能把接口和具体的逻辑实现分开,所以想局部重构都没戏,如果刚才的步骤设计程序结构的时候不是这样,而是先抽象出核心的操作来

a. 入口 解锁

b. 让发动机工作起来

c. 给变速箱发指令让改变发动机状态

d. 改变车的方向

e. 保持发动机和车的方向状态

ok,现在步骤看起来就完全不是那么回事了,但是程序设计这才是开始,你要把现实的步骤抽象成符合程序逻辑东西,面向对象么,发动机肯定是封装好的一个类可以让你做很多操作,变速箱是在发动机更高层的一个封装,改变方向的操作很可能是封装在悬架或者其他某些汽车部件类里面的。所以你可以得到如下的结构

首先车是我们要给最上层调用的最高层封装,最初的1-7只是车这个类的公共方法,这是给交互层调用的,所以写7个函数声明就ok了,而这里的1-5要写成接口,并且全部可以写成异步的形式,下面来点对象的事情

发动机提供prepare, ready, run, rate, 以及很多其他的状态和switchto 方法, 变速箱提供gears 状态,和changeTo方法,汽车的一系列部件提供redirect方法,

把具体的异步,多线程的同步等等操作都封装在这5个接口里面,因为这五个接口是解耦合,他们彼此并没有直接的关联关系,所以用异步和多线程的时候就不会有任何别扭的感觉了。

等到都写完了,再回头到那7个公共方法上去

可以在车这个类里面维护几个状态,档位,转速,方向,然后从2开始

2. 调用b,在回调里修改车的各种状态,最终得出车已经readyTo换挡的结论再给回调到用户层,让用户可以执行3,然后依次类推,这样就很顺畅了1-7完全是同步过程又不需要考虑具体的逻辑实现,异步和多线程都是封装在更底层的类里面的和最上层的调用没有直接逻辑关系,这才是面向对象啊。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值