正文重要记录重构时的一对增选和化解的题目,项目的目录结构能看到你的开销经历

前段时间和同步事一起重构了六个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层的集体和调用方案

相关文章