如何给UIViewController瘦身
本文转载至 http://www.cocoachina.com/ios/20141128/10356.html
随着程序逻辑复杂度的提高,你是否也发现了App中一些ViewController的代码行数急剧增多,达到了2、3千行,甚至更多。这时如果想再添加一点功能或者修改现有逻辑变得让人无比头疼。如果你遇到了这类问题,那是时候停下来了,思考一下如何更好地组织代码,给VC瘦身。本文将会阐述如何结合MVC的思想帮你的VC瘦身同时提高复用和可扩展性。
一、开发中常见的现象和缺点
iOS中最常见的一种设计模式就是MVC,但在实际开发过程中,我们因为这样、那样的原因让单纯的ViewController变成了集Model,Controller以及View的一个大集合,这样势必就会导致VC的代码容量呈几何增长。这样的代码会存在以下几个问题:
1、不利于后续维护
代码在一个公司的存活时间通常远长于你在公司的时间,你是否也在接手现有项目以后边看代码边在心里默念“a piece of shit”,我想没有一个人希望之后接手你代码的人有一天看你代码的时候也在心里默念着同样的话。作为一个有追求的程序员,或者说为了不被以后的同事骂,我们必须要为自己的代码负责,避免动辄就是几千行的一个源文件。你自己写的都不愿因看,更何况后续接手的人呢。
如果项目进度很赶,当时没有时间对代码进行合理的拆分和重构,后续也一定要抽出时间来填一下自己挖的坑。你可能会说,公司一直都很忙没有时间留给你去重构。我只能说要不就是你自己不会安排时间,要不就是这个公司只把你当代码搬运工。站在长远发展的角度上,要么改变自己,要么炒了老板。
2、不利于支撑UI的变动
试想如果有一天你们的App的UI风格需要改变,大量的View需要改变,在一个几千行的VC中删删改改是什么感受。可能因为改动UI的时候一个不留神错改了Model或者Controller的东西,导致程序都不能正常运行。而且改动的范围不能控制在一个较小的范围,测试回归起来的工作量也是很大的。
3、不利于复用
如果你的App一开始只支持iPhone版本,所有的一切都那么自然,程序也运行的很好。突然有一天老板告诉你说公司业务发展的不错,为了扩大市场需要退出iPad版,这个时候如果仅仅只是iPhone版本的放大版,那么你需要做的可能就是添加一些view的自适应就好了。但现实并不总是理想,如果iPad版的需要重新设计,按钮的位置都变动了(参考上面的第二点),这个时候难道需要把所有的代码都改一遍?这尼玛工作量也太巨大了吧。
通常iPhone版本和iPad版本不管UI怎么变,业务逻辑只是基本相同的,那么如果当初我们的代码层级比较清晰,是不是Controller和Model层就可以完美的复用呢,针对不同的版本换一套View即可,这个是不是方便多了,自己感受一下。
二、如何解决这些问题
第一部分说了这么多终于点题了,如何使用MVC模式更好的给VC瘦身,提高复用性和可维护性呢?我画了下面一个图:
解释一下上面这幅图,一个完整的模块被分为了三个相对独立的部分,分别是Model,View,Controller,对应到我们App中的依次为继承自NSObject的数据中心,承载UI展示和事件响应的View以及我们最最常用的UIViewController。
其中VC持有View和Model部分,View通过代理或者Target-Action的方式把用户的操作传递给VC,VC负责根据不同的用户行为做出不同响应。如果需要加载或刷新数据则直接调用Model暴露的接口,如果数据可以同步拿到,则直接使用获取到的数据刷新View。如果数据需要通过网络请求等其他异步的方式获取,VC则通过监听Model发出的数据更新(成功或失败)通知,在收到通知时根据成功或者失败对View进行相应的刷新操作。可以看出来整个过程中View和Model是没有直接交互的,所有的操作都是通过VC进行协调的。
进过MVC分层的好处:
1、VC代码量骤降,易于维护
可以看到拆分后VC中就仅剩下事件的响应操作了,所有显示相关的东西都被单独抽取出来,所有的网络请求以及数据缓存都被提取到出去了。VC中的代码会大幅度减少,在我们项目中的实践结果为:拆分前一个VC的代码行数为2600行,拆分后VC的代码行数仅剩不到600行。
2、复用性提高
拆分后如果App需要对UI展示进行大改,那么你的改动基本上都会停留在View模块中,你可以选择在现有的基础上改,也可以选择从写一个。只要业务不变的话,Model和VC模块完全不需要修改。这样改动的范围较小,对开发和测试都比较友好。
拆分后如果App需要支持iPad版本,那么你需要做的就只是重写一个View然后放进去就好了,Model和VC模块同样基本上不要做任何修改,想想是不是还有点儿小激动呢。
三、总结
使用MVC模式可以达到帮VC瘦身,可以到到提高复用性和可维护性的效果,同时也会让原本一个整体的业务代码,分散到各个不同的地方。实际使用中我们需要具体问题具体分析,如果一个VC中的东西本身就很简单,那么完全可以放在一起,因为即使全部放在一起也就几百行代码。例如App中常见的Copyright界面,本身就是加载一个html就搞定了,就完全没必要搞得那么复杂;如果一个VC已经很复杂,代码动辄几千行了,那么就需要拆分,达到更好的复用以及方便维护的目的。
写了几年代码了,见过所有东西都往一个源文件里面塞的,也见过一个本就很简单的东西被设计模式搞的四分五裂的,不要为了用设计模式而用设计模式。把握好度很重要,能用子弹解决的问题就不要动大炮。
代码重构应该是一个持久的过程,在开发的过程中就时不时的对现有不合理的地方进行重构,而不是等待问题已经很多了才想起重构来。千里之行始于足下,千里之堤溃于蚁穴。
如何给UIViewController瘦身的更多相关文章
- iOS:使用MVC模式帮ViewController瘦身
如何给UIViewController瘦身 随着程序逻辑复杂度的提高,你是否也发现了App中一些ViewController的代码行数急剧增多,达到了2,3千行,甚至更多.这时如果想再添加一点功能或者 ...
- iOS UIViewController的瘦身计划
代码的组织结构,以及为何要这样写. 那些场景适合使用子控制器,那些场景应该避免使用子控制器? 分离UITableView的数据源和UITableViewDataSource协议. MVVM的重点是Vi ...
- MVVM与Controller瘦身实践
MVC是一个做iOS开发都知道的设计模式,也是Apple官方推荐的设计模式.实际上,Cocoa Touch就是按照MVC来设计的. 这里,我们先不讲MVC是什么,我们先来谈谈软件设计的一些原则或者说理 ...
- Drawable实战解析:Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)
Android XML shape 标签使用详解 一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...
- Android APK瘦身之Android Studio Lint (代码审查)
******** ******** 第一部分: 瘦身内容介绍 ******** ******** 项目新版本的迭代接近尾声, 因为历史累积问题, 导致有很多无效的资源让已经臃肿的APK变得更肿, 因此 ...
- 【直播】APP全量混淆和瘦身技术揭秘
[直播]APP全量混淆和瘦身技术揭秘 近些年来移动APP数量呈现爆炸式的增长,黑产也从原来的PC端转移到了移动端,通过逆向手段造成数据泄漏.源码被盗.APP被山寨.破解后注入病毒或广告现象让用户苦不堪 ...
- APK瘦身记,如何实现高达53%的压缩效果
作者:非戈@阿里移动安全 1.我是怎么思考这件事情的 APK是Android系统安装包的文件格式,关于这个话题其实是一个老生常谈的题目,不论是公司内部,还是外部网络,前人前辈已经总结出很多方法和规律. ...
- iOS可执行文件瘦身方法
缩减iOS安装包大小是很多中大型APP都要做的事,一般首先会对资源文件下手,压缩图片/音频,去除不必要的资源.这些资源优化做完后,我们还可以尝试对可执行文件进行瘦身,项目越大,可执行文件占用的体积越大 ...
- 清理iOS工程里无用的图片,可瘦身ipa
工程在经过多人后,往往会出现较多的垃圾,导致打包出来的ipa文件偏大,有时候我们会通过清理代码来给程序瘦身,而瘦身ipa效果明显的,主要通过清理程序里的无用图片. 推荐一个清理图片的应用 https: ...
随机推荐
- MAX() OVER() 函数
SELECT T1.FRAMENO, T1.UNDERTAKER10,T1.STATUSCODEDATE10, MAX(T1.STATUSCODEDATE10) OVER(PARTITION BY T ...
- 解决WCF部署到IIS出现“证书必须具有能够进行密钥交换的私钥,该进程必须具有访问私钥的权限”
访问WCF服务时,出现异常详细信息: System.Security.Cryptography.CryptographicException: 密钥集不存在.ArgumentException: 证书 ...
- 在typescript中import第三方类库clipboard报错
一.问题 在实际开发项目中就遇到了这样的问题,需要在Vue+Typescript项目中添加复制文本的功能,就找了clipboard插件,先是新建了一个新的项目用来实验看看是否好用,都写好了以后发给别人 ...
- path.join 与 path.resolve 的区别
1. 对于以/开始的路径片段,path.join只是简单的将该路径片段进行拼接,而path.resolve将以/开始的路径片段作为根目录,在此之前的路径将会被丢弃,就像是在terminal中使用cd命 ...
- Linux基础学习1
安装问题 随意下载的:CentOS-5.5-i386-LiveCD-Release2.iso Live CD 是可以直接运行在内存当中的,而不是安装镜像. 如之前玩过的BT5一样,把BT5-LiveC ...
- eclipse中mybatis generator插件的安装与使用,实现自动生成代码
git地址:https://github.com/mybatis/generator 下载后解压: 选择任意一个版本的jar放到eclipse的features目录下即可 选择任意一个版本的jar放到 ...
- 区间最小值(2) (线段树 更新区间)2015年 JXNU_ACS 算法组暑假第一次周赛
区间最小值(2) Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other) Total Subm ...
- linuxshell编程之变量
变量分类: 用户自定义变量:局部变量 定义格式:变量名=变量值(*等号左右不能有空格,加了空格会报错) 调用格式:echo $变量名(调用的是变量名等效的值) 变量叠加:$x=123,y=" ...
- sql语句中几个需要注意的点
1.在写join语句的时候,一定要注意不要漏了on语句,例如: Select * from Student inner join Sc on Student.Sno=Sc.sno 2.having语句 ...
- 【前端阅读】——《活用PHP、MySQL建构Web世界》摘记之高级应用
一.高级应用 1.计数器 计数器的原理很简单,只有两步: 第一步就是读写一个数字,第二步就是显示出来.一般CGI'大多直接写到文件系统,当然也可以利用MySQL来存储这个数字,完成第一步的操作. 第二 ...