类型目录结构比较正常的出半点种。在总色里摘的凡 MVC

前段时间和同转业一样于重构了少单
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 +
按工作划分项目层级的不二法门。具体的如下图:

亿万先生官方网站 1

全方位项目要分为4单文本夹,分别是:

  • AppDelegate: 程序入口。
  • Classes: 存放主要代码文件。
  • Resources: 存放资源文件,如图、音频、视频、 HTML 文件等。
  • Supporting Files: 存放配置文件,如 Info.plist、main.m、pch 文件等。

要是里面 Classes 目录下,又精心分要下图:

亿万先生官方网站 2

  • 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层的组织及调用方案

相关文章