设计模式-《重构》读书笔记及 APP 重构心得。基于 MVC 的类别重构。

项目目录结构比较常规的有两种,在老项目里选择的是 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层的团伙和调用方案