iOS类似朋友圈的结构设计(上层)

读过很多设计模式,看过很多开源代码,却依然被产品整的死去活来. 过完春节,开年空的这几天终于可以歇一会,写写博客.

现在我们从实战出发,聊一聊类似朋友圈这样的页面应该如果去设计,开发.(这里就先抛砖引玉了)

1:确认完需求拿到视觉稿


图1

此时脑子会有无数的设计闪过,如何做每一个层的规划.最后定下来这样的一个流程.

图 3

View: 只是view 用于显示数据  和 事件触发 

ViewManager: 1: 他包含 DataSource 用于提供给ViewManager 的数据(ViewModel) , ViewManager再把数据(ViewModel)赋给View, 让View进行渲染  2:接收View触发的事件,提供给Handler,让Handler进行处理  3:ViewManager 可以是vc , 也可以是NSObject, 如果数据和页面足够简单View本身也可以是一个 ViewManager  4:ViewManager可以包含其他ViewManager

Handler: 1:只是处理 View所触发的事件  他可以是页面跳转, 也可以是触发DataSource的数据更新  2:Handler也可以包含其他Handler

DataSource: 这个数据源 其实是和业务相关的, 把最终处理完成的后的ViewModel 返回给ViewManager 他会给外部提供简单的接口给Handler 使用,  (插入,合并,排序等操作都是在DataSource里面完成)

Manager: 这个只是基础的对外提供原始数据的对象 , 你可以把他看成一个网络请求的Manager 或者本地数据 返回的只是最原始的model(单纯描述数据) 不和具体页面有关系 可能这个叫做Service 更好点图已经画了懒得改了.....

Model:基础的数据模型 不和上层业务相关

2:开始干活

那么根据这样的准则我就先拿动态流 举例吧.

看到这样的页面的我们首先会想到的是万能的tableView

我们先进行结构的划分

图 4

先把他定为 2大块 TableView 作为一个 ViewManager    上面的信息页面作为一个ViewManager

先来说下TableView 的ViewManager 这里我们为了方便就直接把 VC作为TableView的ViewManager.当然为了让VC更加干净也可以 TableView开一个TableViewManager 给VC 让VC持有这个TableViewManager. 不过这样就要你需要让VC暴露TableViewManager需要的一些属性和方法(为了偷懒).

遵循ViewManager的准则

DataSource 提供处理完的数据给  vc  vc给予View (也就是上面的Cell)   View(也就是Cell)事件分发给vc 让vc交给handler处理

下面看下代码

DataSource:

图 5

这里 DataSource就是这样只对外提供了一个获取当前数据(也就是一个数组 里面包含了 广告 ,动态 等数据的ViewModel)

VC:

图 6 
图 7
图 8


图 9

图 6: vc持有  Handler 和 DataSource  

图 7: vc从DataSource 获取当前的数据 

图 8: vc 把数据给 tableView 

图 9: View 把事件提交给 vc 让vc 交给 Handler去处理 

(这里有个event. 有些人可能喜欢view的回调用delegate 这样参数可以自解释,不过当要增加一个参数就要改很多地方. 有些人可以喜欢用block方便,参数也可以随意增加. event 无非所有传递都是通过model不用添加额外的方法(懒), 好处不用到处都是delegate 和block回调, 坏处不能自解释,要写注释. 个人喜好这种大家可以按自己熟悉的来我这里先用event.)

这样一整套上层的流程就算定完了.接下来干正事,就是画View(毕竟大量时间都是UI工程师).

3:细分TableView的cell



图 10

对于看起来是一整块的cell来说,数据源只是一个ViewModel,实际上是需要拆分层许许多多的小cell的,无非是关乎性能和关乎更好的维护,后续添加和删除内容更容易(比如后续要接各种广告, 加视频 ,小视频这种需求).这里先这么简单的来拆分一下看到的1,2,3,4,5这么5块(虽然实际上更多 ,不过都是重复的劳动).

我们提出3号这个cell来讲解下. 这是一个有点赞,评论,分享.3个功能的一个cell.

之前说过cell他也不过是一个View,既然是View那他只有2个职责 1:负责渲染 2:触发事件.

以前我们总是碰到model你都没定义好怎么进行View开发呢,写UI的人留出位置等model,然后去处理model去了. 所以这里我们已经理解了交互,UI完全是可以和数据层并行开发的.比如这个点赞,评论,分享的View,对它来说它需要知道什么? 它只需要知道我这个按钮到底是不是点赞的状态.那么写这个点赞View的人只需要对外提供一个Protocol 类似这样


图 11

这个View只要知道 ,是否点赞的状态的就可以,所有渲染都是基于这个Protocol, 这个Protocol交给ViewModel去实现. 而View并不关心到底是什么model,完全可以多人并行开发最后让ViewModel去实现这个Protocol,然后所有工作都完成了.  

(这里到底是只用一个Protocol包含所有View, 还是每个View一个Protocol, 这个和领导争论了很久.  如果是每个View一个Protocol,这样就看起来分的太细, 让后续维护的人看起来很麻烦又不好理解. 但是好处是, 比如这个点赞评论分享的View,详情页面用到,那么就让详情页的ViewModel去实现这个数据,可以复用. 可是也有一个问题,如果视觉设计的2边的不一致,那还是要写2套.  如果是一个Protocol都包含所有View需要的,那么对于单个View来说又看上去太冗余, 职责不单一.  又有人问既然是一个Protocol为什么不直接用ViewModel,这是因为ViewModel会有一些和View显示不相关的方法比如插入,删除等,这些操作是没必要暴露给View. View就只有2件事情 显示,触发,越简单越好,不关心数据,后续即使数据变更也没关系.不用影响到View里面的修改,无非是底层和ViewModel是事情了. 如果大家有更好的思路可以说明下)

所以关于一个View的渲染和触发事件的结构是这样的


图 12

按照这样的结构我们来看 3号这个cell 关于一个点赞事件的 显示 触发 更新的流程


图 13


图 14


图 15


图 16


图 13 点赞的按钮的 的显示是 更具自己 提供的Protocol

图 14  触发点赞的请求

图 15 传递给了可以处理的Handler 进行处理

图 16 Handler选择调用 DataSource  点赞的方法 , 最后DataSource把更新完后的数据扔给ViewManager 说数据更新了 ViewManager再把新的数据给予View

关于DataSource里面的点赞怎么实现的, 是否要加离线点赞,这些都是后话. 这些都是扔给底层的Manager去处理,这个底层Manager后面的文章会细讲.

就这样一个View的从显示到触发事件的流程都跑完, 其他也都依葫芦画瓢(体力活).

4:上层流程的总结

开发中需要注意的点 

1: 关于Handler的拆分 在这里主要把原本在VC处理的业务交给了 Handler .如何让单个Handler不臃肿,比如现在我们的App只把 键盘事件  和 分享 公用的单独作为一个Handler分了出去. 之后随着业务的增加需要思考.

2: 如何细分 View, View分的细开发起来麻烦, View分的大后续维护扩展会很麻烦. 这些都需要根据大家业务本身进行取舍.

3:有时候一个复杂页面有时候会涉及很多结构, 老生常谈如MVC,MVP. 或者MVVM,VIPER. 或者有着你自己思想的结构. 这些也需要看你具体业务进行选择, 比如你的新增业务只有一个Button按下去的事件做跳转,这还需要什么结构.如果后续多了再进行结构的调整.

4:写了这么多, 最后吐槽下,没有什么万能的设计模式, 只有漫漫长夜的加班中的进行代码结构的优化. 

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 传统模式下的开发MVCMVVM基于面向协议MVP的介绍MVP实战开发说在前面:相信就算你是个iOS新手也应该听说过...
    行走的菜谱阅读 3,143评论 1 5
  • iOS网络架构讨论梳理整理中。。。 其实如果没有APIManager这一层是没法使用delegate的,毕竟多个单...
    yhtang阅读 5,160评论 1 23
  • 2017.02.22 可以练习,每当这个时候,脑袋就犯困,我这脑袋真是神奇呀,一说让你做事情,你就犯困,你可不要太...
    Carden阅读 1,321评论 0 1
  • *7月8日上午 N:Block :跟一个函数块差不多,会对里面所有的内容的引用计数+1,想要解决就用__block...
    炙冰阅读 2,468评论 1 14
  • 一, 如果用一部电影来定义戏精的2017年,也许是《醉乡民谣》吧。当她今天焦急地等着一个面试通知,并且越发清晰地意...
    参差参商阅读 342评论 1 0