种类的目录结构能收看你的支出经历,在老项目里选择的是 MVC亿万先生官方网站

前段时间和联合事一起重构了多个APP,正好想写一些重构心得,前日又在微博上看到一长辈推荐《重构》那本书,据他们说是程序员的必读书籍,于是就简单的读了一回,对重构有了更深层次的认识了。这里结合
iOS 项目标重构,谈谈与重构相关的难点,做一下记录及享受。

前言

方今供销社的品类要立异具有界面的 UI
风格,趁此机会正好把品种重构三次,本文主要记录重构时的有的接纳和缓解的难点。

一、《重构》读书笔记

背景

率先说说背景,约等于为啥要重构,因为重构是索要资金的,一不小心修改错了,就会让本来完好的产品出各类题材,所以先计算下为何,重倘诺以下多个难点:

  • 1.没有统一的代码风格
    那几个就比较痛心了,因为历史的来由,大概说那么些序列初期就没有代码规范,在接手项近期,代码风格就相当自由、天马行空。在此时期我重构了一片段,但仍有一大半不正规的代码。
  • 2.臃肿的 ViewController
    这些好驾驭,一个类几千行代码,应该的不该的都挤在共同。
  • 3.麻烦通晓的逻辑代码
    工作逻辑代码混乱不堪,看的胸闷,还不敢乱删。
  • 4.混乱的类调用
    不曾强烈一个类该做什么样,全都堆在联名。

追求代码品质是一个完好无损程序员对团结的渴求,所以趁那个空子,决定把整体项目重构一回。

1.1 重构的定义

  • “重构”这一个词有二种区其他概念:
    • 首个概念是名词方式:
      重构(名词):对软件内部结构的一种调动,目标是在不更改软件可观看行为的前提下,升高其可掌握性,下降其修改花费。
    • 其次个概念是动词形式:
      重构(动词):使用一名目繁多重构手法,在不更改软件可观望行为的前提下,调整其结构。

重构的概念表明了两点,第一,重构的目标是使软件更便于被清楚和改动;第二,重构不会改变软件可观看的作为——重构之后软件功用如故。

架构的采用

现阶段在 iOS 开发上有很多看好的架构形式,如 MVC、MVVM、MVCS、VIPE汉兰达等等。对此作者的见识是:架构的精选要结成具体的图景,比如工作的复杂度、开发人士的接受程度,以及重构的时日周期等等,选择一个对的架构比采用一个扑朔迷离的架构更为主要。
在老品种里甄选的是 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.拆分后的模块要硬着头皮升高可复用性,尽量做到D奥迪Q3Y
  • 3.抓实拆分模块后的抽象度

胖 Model 的问题

上文精简 ViewController 把代码都参加到 Model 里去,所以会招致胖 Model
的题材。对此小编的明白是,除了优化外,代码的总量是确定的,一方的简洁必然会导致一方的增多,而
Model 在此地是用来帮 ViewController 处理业务逻辑的,约等于说胖 Model
包涵了一部分弱业务逻辑。胖 Model 要高达的目标是,Controller从胖 Model
这里得到数码将来,不用额外做操作如故只要做万分少的操作,就可见将数据直接使用在
View 上,从那点上看胖 Model 也是足以承受的。

单元测试

老品种是不写测试代码的,也没有写单元测试的标准。想想一个类堆砌几千行代码,想写也不佳入手,但既然重构了,单元测试也得补上。
单元测试对于当下来说,就是为着便利测试一些功用是还是不是正常运转,还有调试接口是或不是能正常使用。
偶尔你或者是为着测试某一个网络接口,然后每便都重复开动并且经过重重操作之后才测试到了分外网络接口,若是选用了单元测试,就足以一向测试这些格局,绝对有利广大。
比如说由于修改较多,想测试一下分享功效是不是正常,这时候就有用了。大概直接看有的接口再次来到的数量也会尤其直观,不用启动全套工程。

TODO

在那也列举多少个接下去可以做的事,先添加到 ToDoList 里。

  • URLRoute

  • 模块化

最后

其实计算起来就三点,尽量确保:

  • Controller 里的代码尽只怕的少
  • Model 的意义尽可能的共同体
  • View 尽大概独立

就能营造一个便于保证,便于协同的档次。

正文只是在项目重构中总括的一相比较关键的点,并不代表都以最优解。而小编在档次的架构和代码的集体上经历尚浅,若本文有怎么着错误恐怕有更好的不二法门请直接提出,欢迎交换探讨。

Reference

iOS应用架构谈
view层的团体和调用方案

相关文章