App UI 体验设计:内存、磁盘与网络如何优雅的同步数据?

开发一款App,就犹如写一篇命名文章或设计一栋楼房。在你动笔之时,文章已然成竹于胸;在你搬起第一块砖,楼房的概貌已经定型。故在你敲下第一行代码之前,务必要仔细想好App的架构才行。

我们知道,App中数据无外乎存在于这几个地方:内存、手机磁盘与网络上。编程其实就是对这些数据的迁移,上传或下载,再搭配友好的界面呈现给受众。你发一条朋友圈,数据由手机上传至服务器,然后你的好友再将其刷新下载至它自己的手机,完成阅读~

那么,作为一名程序猿(媛),你会如何设计用户按下“发送”按钮之后的数据迁移与界面更新之路呢?

方法一:

这里写图片描述

View通知ViewController,“快把这条动态分享到朋友圈~”,为了界面友好性,然后ViewController显示一个对话框让用户进行等待,此时ViewController将这条动态交付给Network,开始三次握手,建立连接,写数据,读取响应结果最后关闭连接,完成数据发送。Network将发送成功结果告知ViewController,“已顺利发送到朋友圈,不谢”,ViewController隐藏等待对话框,并通知View去绘制这条动态。

发送路线:View->ViewController->Network
回调路线:Network->ViewController->View

一切逻辑看起来都是那么的正常,当然这是以程序员的眼光。而在手机前盯着屏幕的网友们可能就无法忍受界面弹出对话框不停旋转等待发送的设计了,他们愤怒的评论会铺天盖地。

于是,方法二:

这里写图片描述

你尝试着在ViewControllerNetwork中,引入了Model层,并打算去掉烦人的loading对话框。

数据沿着View->ViewController->Model迁移,而后Model层同时做两件事情:

  • Model->ViewController->View 立刻回调ViewController,通知刷新界面
  • Model->Network 开始将数据发送至网络

此时动态已经显示在了界面上。在由Network完成发送之后,数据再一次的沿着路线Network->Model->ViewController->View通知确实是完成发送了。

看起来比上次好很多了。但是当用户重新打开手机之后,有明显的延迟感来显示刚才发送的动态。哪里有问题?

问题就在于Model层。启动App之后,ViewViewController查询数据,ViewControllerModel层拿数据,而此时Model层还没有数据,因此又得通过Network拿数据进行等待,因此便有了数据延迟显示的问题。

方法三:

这里写图片描述

Model换成了Persistent Model,并引入了Application Logic组件。

Application Logic组件用于两个用途:

  • Network进行数据同步
  • 将数据更新至Persistent Model

即业务逻辑迁移至了Application Logic组件中,它扮演的是数据路线的调度器与通知器。系统各个组件都做着自己分内的事情,解耦合,易测试。

发送数据:View->ViewController->Application Logic->Persistent Model
当写入Persistent Model成功,进行Callbac通知View绘制:
Persistent Model->ViewController->View

与此同时:Application Logic->Network
当发送至Network成功,进行Callback通知View绘制
Network->Application Logic->Persistent Model->ViewController->View

这一切看起来是那么的完美。Run~~~生活总在你洋洋得意的时候,给你一记重拳…连续发送好几次之后,有时候按下了发送,界面却迟迟没有及时刷新,What’s wrong?

原来,我们的任务线程现在已经too busy不堪重负了。解析图片,写入数据到磁盘,进行Http数据上传,又要写入数据,又有新的Http数据上传,在网络状况特别脆弱的情况下,可能因为一次Http长时间的调用,后面所有的操作就都全得wait啊!

这里写图片描述

方法四:

最终…你讲这一个有一个的任务进行划分,分别引入至两个不同的任务队列中,互不影响。此处应当有掌声。

这里写图片描述

估计有的同学其实已经知道了,这其实是2015年Android开发者峰会上Yigit Boyar和Adam Powell通过一款小软件“Puppy Love”向大家讲解的知识点:用户体验的设计 (Architect for UX)。总结下来如下:

Design for offline (离线设计):

  • UI的数据从Model层获得
  • Application Logic 负责同步Model和Server
  • 二者互不干涉

而关于Application Logic类的设计:

  • 如果有可能,请使用依赖注入
  • 考虑使用它的副作用
  • 避免因为它影响性能

关于Network的设计与建议:

  • 你的后台就是为你的App而设计的
  • 在服务器端做尽可能多的事情
  • 给客户端传递Metadata信息
  • 尽可能的一次请求多条数据

什么叫做Metadata信息,就是当你想要获取图片的时候,你不止拥有图片url这一个资源

这里写图片描述

但是在这个图片完全下载成功之前,你要想显示图片就比较棘手了,因为你不知道它的宽度和高度,创建placeHolder都比较棘手,所以提供我们需要更多的围绕着这个图片的metadata信息:

这里写图片描述

现在知道了图片的宽度和高度,对于用户界面体验是不是有很大的帮助呢?

在实际开发中,除了NetworkPersistent Model,还应该引入Memory层,进一步尽速数据的展示与界面更新。这样数据迁移路线就变成了
View->ViewController->Memory->Persistent Model->Network
而数据同步路线也变成了
Network->Persistent Model->Memory->ViewController->View

这样在App内,数据同步逻辑按照此方式既简单正确,而又清晰易懂,是不是的确是一种优雅的方法呢~

欢迎关注微信公众号:coodelife

A store about code and life

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值