几个步骤,让你的 iOS 代码容易阅读
本文翻译自 Making your iOS application easy to read with these simple steps.
优秀的程序员会用尽可能简单的方式来解释他们的代码,即使是物理学家都可以用一张白纸和一只铅笔来解释虫洞,我们又何尝不可?
我会尽可能让代码写地简单、易读,包括选择合适的变量名、使用编码规范(code conventions)等等,但还是缺了点东西,理解代码不应该是去理解“如何”实现的,而是要理解想要“达成”什么。
甚至可以说要让读代码像读小说一样,而不是一大堆代码。
下面讨论三大主题:
问题
阅读其他人的代码可能会非常折磨,如果不提供合适的上下文,我们会迷失在寻找某个函数或属性的意义中。
建议
不论是二进制语言、低级语言还是高级语言,语法都在变得越来越友好,以便吸引更多开发者。而随着语法变得更接近英语,我们的代码也应该简明扼要、不言自明。
结果
写出良好的代码,读起来像小说一样,容易阅读和理解(即使没有给出上下文)。
函数命名
正确的方式是:
我们写函数时都会假设阅读它的人拥有足够的上下文,能够理解函数想实现什么。用模糊的含义来命名函数,例如“handleRedView()”会引起很多问题,”RedView”是啥?这个函数主要是想干啥?
所以在某些情况下函数的用途会很模糊,如果没有提供足够的上下文,阅读起来会非常困难
我们可以把函数的用途分为四类:
- 通知(Informer)函数
- 管理(Management)函数
- 路由(Router)函数
- 执行(Execution)函数
1. 通知函数
通常会触发路由/管理函数,例子如下:
delegate.dataHasUpdated()func dataHasUpdated()
{//通知某事的发生}// 通知函数
override func engineStarted()
{super.engineStarted()handleCarStarted()}
复制代码
回调函数,通知某事已经/即将发生,并给机会进行响应。
大部分情况下用于被代理(delegate)触发的操作,或是通知(notification)处理函数。
2. 管理函数
用于联合多个函数以实现更高级的用途,不需要依赖参数,block 中的所有代码都会执行。
// 管理函数
func handleCarStarted()
{turnLights(on: true)turnAC(on: true)
}
复制代码
上面的函数包含所有需要的信息,汽车启动时执行这些函数,此时我们不关注这是“如何”实现的,而是关注它做了“什么”。
3. 路由函数
用于联合多个函数以实现更高级的用途,需要依赖一些参数,只在我们想执行的时候才执行。
// 路由函数
private func turnLights(on shouldTurnLightsOn: Bool)
{if shouldTurnLightsOn{turnExteriorLightsOn()checkForBurnedBulbs()}else { turnExteriorLightsOff() }如果 if 语句只执行一件事,我喜欢把 "if" "else" 和执行语句写在同一行,这样代码读起来会更流畅。
复制代码
路由函数通常同于指向执行函数,但在某些情况下,如果逻辑代码不超过一行,也可以包含自己的逻辑。
4. 执行函数
函数名字的具体实现。
// 执行函数
private func turnExteriorLightsOn()
{leftFrontLight.isOn = truerightFrontLight.isOn = trueleftBackLight.isOn = truerightBackLight.isOn = true}private func checkForBurnedBulbs(){for lightBulb in bulbs where !lightBulb.isUseable{Dashboard.(errorType: .lights)break}}
复制代码
这样就能写出一个干净、简短的类,可读性强,容易维护。
* 谨记一项原则,每个函数都应该只有一个责任。
避免在函数名称里使用”and“: playAndMinimize() loadAndPlay() 这个坏习惯会打破单一责任原则,写出能够适应两种情况的代码。
避免在函数名称里进行猜测: moveRedViewIfNeeded() 上面的例子会导致后面的程序员必须深入此函数,才能理解触发移动 Red View 的时机,这样不够清晰。
不,layoutIfNeeded() 并不属于这种情况,因为我们知道如果某个 view 的 setNeedDisplay 为 true,就应该重新布局。这种情况在 Swift 语言里很普遍,因为函数基本上都是应用私有的。
注
谈及代码可读性,我首先会想到编码规范(code convention),它们被普遍接受、应用广泛,但使用编码规范并不一定会提升代码质量,虽然有跨应用性但可读性更差。
”is“前缀应该用于布尔型变量和方法,以便解释返回值是布尔类型的。#编码规范
既然”if“语句总是用于布尔值,那还有必要给每个布尔属性都加上”is“吗?为什么苹果要把 Swift 语法从 view.hidden 改成 view.isHidden?我只能想到一种答案……因为**“if view.isHidden”**看起来更自然。
尝试以以下原则使用“is”前缀:
- 如果类的某个布尔属性/方法用于该类(公开)的实例,就有正当理由使用“is”前缀。
public var isHidden: Bool
{return alpha == 0.0}if containerView.isHidden
复制代码
- 如果布尔属性在类内部(私有)使用,前缀就是多余的。
private var positionedVerticaly: Bool{return view.frame.width/2 == centerX}if positionedVerticalyif positionedVerticaly && positionedHorizontallyVSif isPositionedVerticalyif isPositionedVerticaly && isPositionedHorizontally
复制代码
- 如果布尔型属性/方法同时被私有和公开使用,那么应该用计算属性来返回该私有属性值。
public var isPositionedVerticaly: Bool
{return positionedVerticaly}if containerView.isPositionedVerticaly
复制代码
虽然用私有 set 并公开使用该属性也是可以的,但上面这种方式可以实现封装(encapsulation)。
封装用于隐藏类中结构化数据对象的值或状态,防止未授权方直接访问。
en.wikipedia.org/wiki/Encaps…
那如果不是自己直接处理的布尔型,如果如何命名呢?
private var playerIsPlaying: Bool
private var gridConstraintIsEnabled()
“is” 需要指向某个东西:view.isHidden, “is”指向 view。上面的例子里使用了此原则,playerIsPlaying,“is”指向 player。
谨记:开发者通常会在阅读属性声明之前先阅读函数内部的代码,尝试搞明白这些属性的用途。
/if playerIsPlaying { }/ 对比 /if isPlayerIsPlaying {}/
复制代码
哪个更自然?我想你已经有答案了。
几个步骤,让你的 iOS 代码容易阅读相关推荐
- iOS代码混淆安全加固
文章目录 自己创建脚本文件进行代码混淆 iOS代码自动混淆 最近公司扫描App漏洞,提出要给App做代码混淆加固,以提高反编译逆向难度.对于Android应用直接用360安全加固即可:但对于iOS应用 ...
- iOS代码编程规范 根据项目经验汇总
带出几十位从零开始学iOS的实习生或试用期的开发人员后,觉得真的是千人千面,每个人写的代码都风格迥异,如果没有一个文档规范,每次都和新人进行口头的说教,大概自己是不用敲代码了,所以吃了亏了就开始编写i ...
- IOS代码实现常用控件UIButton、UISlider、UISwitch、UISegmentedControl
IOS中最常用到的控件UIButton.UISlider.UISwitch.UISegmentedControl通过Xib文件拖动生成非常简单,其实用代码实现也是一样的简单,当然,用代码实现能够掌握到 ...
- TypeScript的安装步骤、运行问题及代码的简单运行
TS 和 JS 相对比的优势 TypeScript的安装步骤.运行问题及代码的简单运行 TypeScript学习笔记1:变量赋值及书写方式 TypeScript学习笔记2:数据类型 TypeScrip ...
- 对称加密算法原理--OpenSSL演示、iOS代码运用及CCCrypt安全隐患
之前介绍了非对称加密算法,这篇文章介绍一下在非对称加密算法出现之前的对称加密算法,常见的对称加密算法.终端演示OpenSSL和iOS代码运用以及CCCrypt的安全隐患等. 对称加密算法:明文通过密钥 ...
- 插件代码_我们开源了一款 SonarQube iOS 代码扫描插件
背景: 我们在公司(好未来)内部开发了一套基于 SonarQube 的静态代码扫描服务,得益于 SonarQube 开源版本本身的功能,我们可以直接复用支持主流的编程语言,但 SonarQube 的开 ...
- ios 代码截屏模糊问题解决办法
ios 代码截屏模糊问题解决办法 参考文章: (1)ios 代码截屏模糊问题解决办法 (2)https://www.cnblogs.com/gaoxiaoniu/p/5941284.html (3)h ...
- ios APP加密探究几维安全iOS 代码混淆效果参考
几维安全ios代码混淆效果参考: 什么是加密 加密是在二进制的程序中植入一段代码,在运行的时候优先取得程序的控制权,做一些额外的工作.大多数病毒就是基于此原理. 加密作用 加壳的程序可以有效阻止对程序 ...
- 绕过 iOS 代码签名验证 ldid
目录 绕过 iOS 代码验证 ldid Homebrew 绕过 iOS 代码验证 iOS 的代码验证分为 2 个环节: 签名验证,用于确认代码是经过苹果授权的 有效验证,用于确认代码没有被修改过 以下 ...
最新文章
- SpringBoot+Mybatis+Swagger2环境搭建
- yum使用时 could not resolve host 报错的解决方法
- html怎么调用微信api接口,JFinal Weixin 学习笔记(6)-- 获取微信接口调用凭据
- python3之subprocess常见方法使用
- ibm z系列服务器 cpu,低调发布:看IBM System Z系列大型机CPU
- SSH之Hibernate总结篇
- 【Python CheckiO 题解】Largest Rectangle in a Histogram
- 《MATLAB R2012a超级学习手册》一第1章 MATLAB概述
- Unity 接入科大讯飞进行在线语音合成
- 【精品,面试之前必读】【转贴】安氏大俗商业学(2005-8-28)
- 远程服务器连接计算机和用户名填写,windos系统服务器:添加远程连接用户名方法...
- 02读书笔记:《编码》-隐匿在计算机软硬件背后的语言(12-14章)
- 解决使用ssh工具远程连接到服务器上因为网络波动而需要重连的问题
- 软件测试行业还能干多久?35岁真的会直接淘汰吗?
- 【手把手教学】利用七牛云免费CDN服务为自己网站启用图片CDN加速 - 免费版10G/月
- UI设计好学吗?UI设计的流程是什么
- slowfast网络解读
- linux文件管理器打不开
- 计算矩形面积的程序python_python实现用类读取文件数据并计算矩形面积
- 大数据告诉你,世纪佳缘都是谁在相亲(python爬虫分析,附全部代码)
热门文章
- AI发展进入2.0时代!英特尔在落地中总结4大经验、分享7个案例
- AI赌神超进化:德扑六人局击溃世界冠军,诈唬如神,每小时能赢1千刀 | Science...
- Beego的controller怎么用嵌入实现继承问题
- Python Numpy 从文件中读取数据
- Java foreach与for循环性能对比
- IntelliJ IDEA(2017)安装和破解
- linux iptables导致httpd网页打不开
- AWS S3宕机的启发: 云必须分散化
- 加大力度改革 成都公安提高服务金融安防建设能力
- php PDO php.ini