前段时间和共业同样由重构了零星个
APP,正好想写有重构心得,前天又当知乎上收看同样前辈推荐《重构》这本开,据说是程序员的必读书籍,于是就概括的念了扳平满,对重构有了再甚层次之认了。这里做
iOS 项目之重构,谈谈与重构相关的题目,做一下记下与享受。
前言
不久前合作社的类如更新具有界面的 UI
风格,趁此机会正好把路重构一全体,本文主要记录重构时之有的精选与化解的问题。
同等、《重构》读书笔记
背景
第一说说背景,也就算是为什么要重构,因为重构是亟需资本的,一不小心修改错了,就会为本圆的制品产生各种问题,所以先总结下怎么,主要是以下四个问题:
- 1.从未有过统一之代码风格
本条就比痛苦了,因为历史的因由,或者说之路前期便没代码规范,在接项目前,代码风格就是生自由、天马行空。在此期间我重构了同一局部,但据有平等老半休正经的代码。 - 2.臃肿的 ViewController
这好掌握,一个近似几千行代码,应该的免应该的且挤在同。 - 3.不便理解的逻辑代码
业务逻辑代码混乱不堪,看之头疼,还非敢胡乱删。 - 4.混乱的类调用
无显著一个类似该做呀,全都堆在联合。
追求代码质量是一个脍炙人口程序员对自己的渴求,所以趁着这机遇,决定拿整项目重构一整个。
1.1 重构的定义
- “重构”这个词起少种不同之概念:
- 首先单概念是名词形式:
重构(名词):对软件内部结构的一律种调整,目的是当无更改软件而察行为之前提下,提高其可理解性,降低该修改成本。 - 次个概念是动词形式:
重构(动词):使用同样多级重构手法,在无转移软件可观察行为之前提下,调整其布局。
- 首先单概念是名词形式:
重构的概念说明了片触及,第一,重构的目的是要软件再易于为了解和修改;第二,重构不见面改软件而察的一言一行——重构之后软件功能依然。
搭的选项
脚下于 iOS 开发上有那么些热之架构模式,如 MVC、MVVM、MVCS、VIPER
等等。对之我之理念是:架构的挑三拣四而成具体的动静,比如工作的复杂度、开发人员的接受程度,以及重构的时空周期等等,选择一个针对性之架比选一个苛的架构更为重要。
在镇色里挑的是 MVC,对于项目面临之大举景吧,MVC
没有成为制约业务发展之瓶颈,同时考虑到新路之就学成本以及重构时间周期的题目,所以当初路达到还是选择了
MVC。
1.2 为何重构?
-
重构可以助你尽良好的支配自己之代码,它可以用于以下几只目的:
-
重构改进软件设计
只要无重构,程序的计划会日益堕落变质。当众人只是吗短期目的,或是在完全了解整体统筹之前,就不慎修改代码,程序用日益失去自己之构造,程序员越来越难通过翻阅源码而知道原的规划。
得同样件工作,设计不良的主次往往需要再多代码,这常是以代码在不同的地方采取完全相同的口舌做相同的事情。因此改进设计之一个关键取向虽是驱除重代码。 -
重构使软件再易理解
修的眼前有这般一句子话:“任何一个傻子都能够写来计算机可以清楚的代码,唯有写有人类容易懂的代码,才是可以之程序员。”而重构可以要代码结构还清,使代码更爱被清楚。 -
重构帮助找到 bug
对代码进行重构,可以深深明代码的当作,并适用地将新的知情反馈回来,在重构的又,我们得窥见一些代码逻辑写的莫兢兢业业或出题目。 -
重构提高编程速度
出色设计师维持软件开发速度之素,重构可以辅助您再度敏捷地开发软件,因为它阻挡系统腐败变质,它还还好增进规划质量。
-
联合的代码风格
无规矩不化方圆,在镇色里由流程的欠及开发人员的更迭,一直尚未一个集合之编码规范。而在差不多人口付出时,保持统一的编码规范是深有必不可少的,这样好保持代码一致性与
Code Review。所以确定了架之后,接着就是确定编码规范。
脚是编码规范里有急需小心的触及:
1.3 何时重构?
-
怎安排重构时间表?是休是应当每半只月就特意配备简单个星期来展开重构呢?这里需要征,重构不是一样桩理当特别扭出时做的政工,重构应该随时随地进行。不应也重构而重构,我们因此重构,是因想念做别的事情,而重构可以助我们管那些从事开好。
-
老三蹩脚法则(事非了三,三虽重构)
首先次于举行有项事时常不过管去做;第二次举行类似之作业会发出反感,但要得以错过举行;第三破再开类似之事情,就当重构了。 -
加上作用时重构
最广大的重构时机就是是咱们怀念让软件上加新特色的时候,此时,重构的直接原因往往是以帮我们懂得需要改的代码——这些代码可能是人家写的,也可能是祥和写的。 -
修补错误时重构
调剂过程被重构,多半是为为代码更享有可读性。 -
复审代码时重构
代码复审对于编写清晰代码很重要,比如我之代码也许对自身自己的话很清晰,但针对别人则不然,这是力不从心避免的,代码复审会受更多口发会提出有效之提议,然后考虑是不是好通过重构来轻松的落实它。
-
命名
动可读的驼峰命名法去给类、方法、变量命名。
常量应该利用驼峰式命名规则,所有的无非词首配母大写及增长和类名有关的前缀。
1.4 重构的中坚技能:
- 有些步前进、频繁测试
代码分块
在函数分组和protocol/delegate实现中动用#pragma mark
-来分类方法,要准以下一般结构:
#pragma mark - Lifecycle
- (instancetype)init {}
- (void)dealloc {}
- (void)viewDidLoad {}
- (void)viewWillAppear:(BOOL)animated {}
- (void)didReceiveMemoryWarning {}
#pragma mark - Custom Accessors
- (void)setCustomProperty:(id)value {}
- (id)customProperty {}
#pragma mark - IBActions
- (IBAction)submitData:(id)sender {}
#pragma mark - Public
- (void)publicMethod {}
#pragma mark - Private
- (void)privateMethod {}
#pragma mark - Protocol conformance
第二、结合 iOS 项目重构心得
留空白
- 建议采用tabs
而未是利用空格,tabs缩进使用4独空格,确保以Xcode偏好设置来安装。 - 文件了时蓄一行空白
- 据此足的空行把代码分割为客体之逻辑块,而无是坏拮据凑
- 毫不以一行代码结尾处留空格
- 双重毫不以空行(\n)中采取缩进(\t)
2.1 项目目录结构
种之目录结构是付出中极基础之,但为是老关键之,清晰的目录结构能被人一致眼睛就扣留明白该品种之事体以及作用,目录结构为能够影响一个开发者的经历与架构水平。项目目录结构较健康的起零星栽,第一栽是据工作分类,第二种是随模块分类。当然具体还得根据实际的作业需求来开,适合自己的才是最好的。
此出一样首关于项目目录结构的稿子,有趣味的童鞋可以读下:iOS
项目的目录结构能望你的开发经历
代码块缩进
(if/else/switch/while etc.)或者method function
的大括如泣如诉留于此时此刻实行,并前保留一个空格 ,能大概的不用添加
如
if user.isHappy {
// Do something
} else {
// Do something else
}
不推荐
if (user.isHappy ) 多余空格
{ 换行位置不对
// Do something
}
else {
// Do something else
}
2.2 业务与 UI
这边不讨论 MVC 架构和 MVVM
架构,关于架构模式之间的争辩有诸多,个人于支持一个理念:永不局限为
MVC、MVVM、MVP
等等一些架模式,万变不离其宗,真正适用于路之架构才是最为好之架构。刚巧接手的原本路在筹划初期及支付过程中,没有进展客观之计划性,以至于部分控制器过于臃肿,代码量很多都是跨了
1000 行,有的还逾越了 1500
行,而且写的深乱。重构的目的,就是增强代码的可读性和方便以后的掩护,我这里论
MVC 的架构模式,将 UI
部分开展抽离,将工具代码(比如计算球面两点之间的距离)进行包装,并内置了有关的家伙类吃,又针对控制器中之冗余代码进行了整理,使得控制器中之代码减少及前的三分之一以下。分享同布置
cocoa 上的 MVC 架构图:
MVC 架构
花色层级细分
2.3 代码还是 xib、 storyboard?
描绘 UI 界面用代码还是用 xib 一直是 iOS
界的争执,有的人支持被采取代码,有的人赞成被用
xib,巧神之前以博客中也讨论过是题目,并于出了部分建议(个人于赞同):
- 对此复杂的、动态变化的界面,建议以手工编制界面。
- 对于要统一风格的按钮或 UI
控件,建议采用手工用代码来布局。方便之后的改动和复用。 - 于欲来延续或成关系之 UIView 类或 UIViewController
类,建议用代码手工编制界面。 - 于那些简单的、静态的、非主导作用界面,可以考虑采取 xib 或
storyboard 来完成。
此间是巧神关于写 UI 用代码还是用 xib 的系讨论: iOS
开发中之争执(二)
物理层级
上文确认了档次架构是盖 MVC 为主,所以这里推荐应用 MVC +
按工作划分项目层级的办法。具体的如下图:
任何项目根本分为4独文件夹,分别是:
- AppDelegate: 程序入口。
- Classes: 存放主要代码文件。
- Resources: 存放资源文件,如图、音频、视频、 HTML 文件等。
- Supporting Files: 存放配置文件,如 Info.plist、main.m、pch 文件等。
一旦内部 Classes 目录下,又密切分而下图:
- General:存放有通用的接近,如基类、Category、Model 等。
- Sections:按工作模块细分 MVC。
- Helpers:存放各种工具类。
- Venders:存放需要手动引入的老三方库。
- Macro:存放全局头文件,各种宏定义,常量等。
2.4 模块化设计
哟是模块化?比如我们正开码代码的时光,有一个经常用之方(比如要合算球面两接触期间的离),由于这个主意经常用,我们会将当下段代码用出来放到一个公共类里,以便实现代码的复用,这就是简简单单的模块化。关于模块化设计之标准,一员阿里大神的提议如下:
- 逾底层的模块,应该更加稳定,越抽象,越有高复用度。
- 毫无为祥和的模块依赖不安静之模块, 减少因。
- 每个模块只做好一码业务,不要让 Common
出现(避免同一分外堆不系的代码放上一个模块)。 - 遵照架构的层数从上到下依赖,不要出现下层模块依赖上层模块的观
事情模块之间为硬着头皮不要耦合。
针对模块化设计感兴趣之童鞋可以看下这首文章,绝对干货!模块化与解耦
代码逻辑层级
于代码逻辑上,大致分成 5 层
- 网络层:负责与服务器通讯获取数据。
- 数据层:存储用户的多少,包括外存cache。
- 业务层:包含各种事情逻辑。
- UI数据层:负责提供UI层所欲的数目,UI只和这层打交道。
- UI层:包括ViewController和View,处理用户之输入。
分使项目再度鲜明,开发时好逐层独立,高内聚、低耦合。
2.5 代码规范
至于代码规范,每个程序员遵守的代码规范多多少少且见面有点不同(比如什么时候该空格,常量变量的命名方式等等),之前听一前辈说了,尽量遵循那些“约定俗成”的代码规范,另外在编码时,要保管自己之代码规范总同,别为丁一样种植你写的代码是几只人口联合写的错觉。
-
取名规范
iOS
命名第一注意少个方面,第一凡是可读性强,别人一样看这名字就懂得其的含义和作用;第二凡防止命名冲突,命名时承诺依照驼峰式命名法则,另外如加前缀,比如常量命名一般会于头里加上字母
k。 -
编码规范
关于编码规范来那么些细节需要留意,比如函数方法一般不能够过长;比如实例变量的修饰符要小心;再以尽可能确保
.h 文件精简,API
尽量写于落实公文里……编码时还起其他一些应当小心的,比如写
delegate 的时路应该吗
weak,以避免循环引用;再按经典的圆角问题,过多的行使
layer.masksToBounds
对系的开发非常充分,会使页面变的卡顿等等……这些编码细节产生过多欲专注,就不一一列举了。 -
写注释
形容注释写注释写注释,重要之作业说其三一体。注释可以助任何同事又好的了解您勾勒的代码,还利于温馨从此的读书。
代码规范方,这里也引进一篇对的文章:iOS开发-代码细节优化(长期更新)
复安利一本书,《编写高质量 iOS 与 OS X 代码的 52
个有效方法》,这按照开对编码时许小心的底细刻画的可怜周全,之前读了相同所有,过几龙会再念一整整,并记下。
布局规范
AutoLayout
始终品种是纯 Frame 布局,代码里产生相同可怜堆 Magic
Number,一很堆屏幕尺寸判断,而这些导致了项目里来了多之布局代码,对于正上手项目之总人口的话吧不顶好看懂。所以这次重构整体应用
AutoLayout 布局,摒弃老品种里之纯 Frame 布局方式,精简代码。
Xib/Storyboard
手写 UI 和 Xib/Storyboard 谁优谁劣这里不举行讨论,但产生同等碰自己觉着
Xib/Storyboard 是比手写 UI
要赶快之。而这次重构工作量特别工期紧,所以弃老项目里的手写 UI ,改用
Xib/Storyboard 。
精简 ViewController
就等同有的自己认为是此次重构的基点,也是本次重构的重要性目的所在,精简
ViewController 里的代码,解决老项目蒙 Massive ViewController 的题目。
重要办事分为以下几步:
- 1.封存最重大的任务,拆分其它未紧要之职责。
- 2.拆划分后底模块要尽量提高可复用性,尽量做到DRY
- 3.增强拆分模块后的抽象度
胖 Model 的问题
上文精简 ViewController 把代码都投入到 Model 里去,所以会造成胖 Model
的题材。对这个我之解是,除了优化外,代码的总量是确定的,一着的凝练必然会招致同正在的加码,而
Model 在这边是因此来帮 ViewController 处理业务逻辑的,也就是说胖 Model
包含了有的弱业务逻辑。胖 Model 要达到的目的是,Controller于胖 Model
这里拿到数码后,不用额外做操作还是如做老少之操作,就能以数据直接用在
View 上,从当时点达到看胖 Model 也是足以接受的。
单元测试
总项目是无写测试代码的,也从来不写单元测试的尺度。想想一个类堆砌几千尽代码,想写吧不好下手,但既然重构了,单元测试也得添及。
单元测试对于眼前吧,就是为了有利于测试一些效果是否正规运转,还有调试接口是否能健康下。
有时你也许是以测试某一个网络接口,然后每次都还起动以经过无数操作下才测试到了那个网络接口,如果下了单元测试,就得一直测试大方式,相对有利多。
仍由于修改比较多,想测试一下享受功能是否正规,这时候就闹因此了。或者直接看有些接口返回的数额吧会大直观,不用启动全套工程。
TODO
在当下吗列举两只对接下好做的从,先上加至 ToDoList 里。
-
URLRoute
-
模块化
最后
实际上总结起来便三碰,尽量保证:
- Controller 里的代码尽可能的散失
- Model 的功力尽可能的整
- View 尽可能独立
不畏可知构建一个容易保障,便于协同的类别。
本文只是在档次重构中总的局部较根本的触发,并无意味着都是极端优解。而自我于列之架和代码的团组织上涉尚浅,若本文有什么错误或有重好之计要直接指出,欢迎交流座谈。
Reference
iOS应用架构谈
view层的团队以及调用方案
相关文章
- 原创纯图欣赏| 全球最为特别星巴克、亚洲唯烘培工坊上海店。星巴克被曝用过期5上糖汁 店方称操作失误。
- 欧国联-姆巴佩破门吉鲁建功 法国2-1荷兰。乌姆蒂蒂头球破门建功 法国1-0克服比利时杀进决赛。
- 尤文卫冕意甲不依靠前锋线 前5胜前锋产量尤文最低。卡瓦尼完爆尤文射手群 斑马6前锋难敌对手双子星。
- 意甲-比达尔点杀 尤文1-0米兰豪取6并强11划分领跑。阿莱格里:米兰产赛季争冠 阿梅利亚:尤文骗点球。
- 卡西Ramos为首开自救会议,Real Madrid Club de Fútbol主席施加压力穆帅终放权
- 迪纳塔莱赛季第21球 乌迪内斯同球小胜拉齐奥。意甲前瞻:乌迪内斯被大不高 米兰主场保平争胜。
- 弗格森:买法尔考?曼联没有打算 范佩西凡英超MVP曼联夺冠关键场:客胜领头羊切尔西 曼市德比复仇。
- Ribéry连扇Alaba三耳光,Alaba教小编非常多事物
- betway体育Van Persie是英超MVP,曼彻斯特联赛季总括
- 还以手工绘制图标?不设错过这些网站搜索资源。找图标素材?这些网站够你用了(推荐)