惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

SecWiki News
SecWiki News
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
博客园 - 叶小钗
S
SegmentFault 最新的问题
IT之家
IT之家
大猫的无限游戏
大猫的无限游戏
博客园_首页
Apple Machine Learning Research
Apple Machine Learning Research
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
月光博客
月光博客
酷 壳 – CoolShell
酷 壳 – CoolShell
腾讯CDC
D
Darknet – Hacking Tools, Hacker News & Cyber Security
V
V2EX
阮一峰的网络日志
阮一峰的网络日志
L
Lohrmann on Cybersecurity
量子位
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Tor Project blog
J
Java Code Geeks
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
博客园 - 三生石上(FineUI控件)
Attack and Defense Labs
Attack and Defense Labs
AI
AI
The Cloudflare Blog
T
Tailwind CSS Blog
S
Schneier on Security
爱范儿
爱范儿
PCI Perspectives
PCI Perspectives
Stack Overflow Blog
Stack Overflow Blog
S
Secure Thoughts
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
T
The Exploit Database - CXSecurity.com
博客园 - 【当耐特】
V2EX - 技术
V2EX - 技术
S
Securelist
P
Proofpoint News Feed
T
Threat Research - Cisco Blogs
Help Net Security
Help Net Security
C
Cisco Blogs
N
News and Events Feed by Topic
人人都是产品经理
人人都是产品经理
B
Blog RSS Feed
K
Kaspersky official blog
T
The Blog of Author Tim Ferriss
G
Google Developers Blog
S
Security Affairs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Simon Willison's Weblog
Simon Willison's Weblog

LeanCloud

LeanCloud 无了? - V2EX 8 月 1 日起, LeanCloud 国际版共享域名不再向中国大陆提供服务 - V2EX LeanCloud 凉了吗? - V2EX LeanCloud 将加入心动/TapTap - V2EX 关于我在使用 LeanCloud 时候遇到的的一些情况分享 - V2EX Leancloud 又双叒叕挂了,炸站了 - V2EX 为什么 LeanCloud 中国版云引擎的标准版实例价格是 ¥ 1/天,国际版的是 $1/天? - V2EX leancloud 强制绑定域名, valine 没得玩了 - V2EX Leancloud 又挂了 - V2EX 这回 Leancloud 域名被锁定到底是因为啥 - V2EX Leancloud 挂了 - V2EX LeanCloud 怎么使用 JavaScript 的 API 保存富文本? - V2EX 做了一个 LeanCloud 数据存储的导出工具 - V2EX Leancloud 的价格方案是不是有点不合理啊 - V2EX LeanCloud 发布了多客户端实时同步数据的功能,欢迎试用 - V2EX 如何在 LeanCloud 开通 cdn 加速 - V2EX LeanCloud 的云引擎是什么配置,为什么免费版的性能还比阿里云的最低配要快? - V2EX 有没有 leancloud 代替方案或开源产品推荐? - V2EX 国内短信价格下调 17%, 2016 年 7 月 5 日零时生效 - V2EX LeanCloud 和阿里云到底有什么区别? - V2EX 赞 Leanote - V2EX LeanCloud 的推送服务稳定性捉急啊,两分钟前好好的突然又不行了。。。另外大家都用什么 Android 推送服务,求推荐 - V2EX 又来。。。LeanCloud 中国节点的后端存储集群出现问题 - V2EX Leancloud 又挂了?全国都无法 ping 通 - V2EX leanapp.cn 下域名无法验证微信? - V2EX LeanCloud 你们的 push 是不是挂掉了,发了几个都不行啊 - V2EX 请允许我水一下,每次敲打 AV.Object...,都会让我下意识的乱想,不能好好的工作,你们设计的时候是如何考虑的,虽然我知道是之前品牌的简称…… - V2EX 使用 New Relic 监控云引擎应用的性能 - V2EX 「产品更新」高效内存存储服务 LeanCache 正式发布 - V2EX 基于 LeanCloud 云引擎的 Web 全栈方案: LeanEngine-Full-Stack - V2EX 「产品更新」2015 年 10 月 LeanCloud 产品更新汇总 - V2EX LeanCloud 的 PHP SDK 发布了 「重要的事情说三遍」将数据安全捍卫到底:权限管理( acl)文档全新发布 「更新日志」2015 年 9 月 LeanCloud 更新汇总 - V2EX 有 leancloud 的人在吗? - V2EX LeanCloud 中的 Relation 是不能同时 add 和 remove 的么? - V2EX LeanEngine 2.0 升级 3.0 指南 - V2EX 云代码 通过 leancloud 的命令行部署失败 - V2EX 如何避免使用 JS sdk 的页面被恶意使用网页开发者工具写个死循环调用 leancloud API? - V2EX 创业公司,北京 iOS 主程, 30k+, React Native, LeanCloud 用户。 - V2EX 我 leancloud 账号用 gmail 邮箱注册,但是忘记了登录密码,申请更改密码但是验证信息收不到,怎么破 - V2EX LeanCloud 发布简单好用的 Web 统计 - V2EX 如何在 React Native 中使用 LeanCloud? - V2EX LeanCloud 数据存储起码要交 200 块才能给数据表加设值唯一字段?? - V2EX Web 实时通信 Demo - V2EX 基于 LeanCloud 的 JavaScript 实时对战游戏简单 Demo - V2EX 对六月六日 LeanCloud 多项服务发生中断的说明 - V2EX LeanCloud JavaScript 发送短信 LeanCloud JavaScript 推送 SDK - V2EX
怎样才能写得一手好代码? - V2EX
LeanCloudRRY · 2016-05-20 · via LeanCloud

「壹期壹问」 VOL.4 收录的问题

真正优质的代码具备什么条件?如何高效的编写优质代码?——来自用户 yuklng

来自 LeanCloud iOS 开发工程师陈宜龙的回答

真正优质的代码具备什么条件?

优质的代码基本的条件:轻量级、低耦合(松耦合)、易替换、易删除。

什么叫低耦合?

你如果可以从你的代码中删除某一模块而不用因此去重写其他模块的话,你的代码就通常被称为是低耦合的。

我们都喜欢轻量级的框架,因为你应该时刻保持着这样的警觉:迟早有一天,这个库、这坨代码会被替换、移除掉。

这可能让你联想起了 iOS 领域一个教科书级别的事件—— ASI 切换 AFN 。 ASI 曾经是 iOS 开发首选的第三方网络框架,后来作者宣布停止维护,开发者纷纷开始迁移到 AFN 。它教会我们一个道理:

让你的代码「易替换、易删除」,第三方框架代码质量是一方面,使用者也有责任。

如何高效的编写优质代码?

想写优质代码,首先要敢于写垃圾代码。

正如程序员心中的上古巨神 Alen Jay Perlis 在 《 Epigrams on Programming 编程警句》 所说:

Everything should be built top-down, except the first time.

凡事都应该高屋建瓴,除非你是第一次干。

所以,在 beta 版本里犯错,上帝都会原谅。

不要在开始写一个应用之前就去想着能写一个万全的架构。道理很简单,就像你在早上 8:00 出门上班前许愿「一路绿灯」,即使当时愿望实现了, 8:00 全北京的灯都变绿了,但等你到下个路口,一样还是该红灯时红灯。我们是很难预先猜测,但我们却可以在发生小变化时,就及早去想办法应对发生更大变化的可能。也就是说,等到变化发生时立即采取行动。

第一次的时候尽管大胆的去写一堆乱七八糟的代码。

但垃圾代码始终还是要转换成优质代码的,如何转换?遵循「开放-封闭原则」,即 The Open-Closed Principle (简称 OCP )去转换:

这个原则其实是有两个特征,一个是说 「对于扩展是开放的, Open for extension 」,另一个是说 「对于更改是封闭的, Closed for modification 」。我们在做任何项目的时候,都不要指望项目一开始时需求确定就再也不会变化,这是不现实也不科学的想法,而既然需求是一定会变化的,那么如何在面对需求的变化时,设计的软件可以相对容易修改,不至于说新需求一来,就要把整个程序推倒重来。

上面是《大话设计模式》中的一段话,书中也给出了一个例子:

比如你在写一个加法程序,你很快在一个 client 类中就完成。此时变化还没有发生。然后我让你加一个减法功能,你发现,增加功能需要修改原来这个类,这就违背了「开放-封闭原则」,于是你就该考虑重构程序,增加一个抽象的运算类,通过一些面向对象的手段,如继承、多态等来隔离具体加法和减法与 client 耦合,需求依然可以满足,还能应对变化。这时我又要你再加乘除法功能,你就不需要再去更改 client 以及加法减法的类了,而是增加乘法和除法子类就可。即面对需求,对程序的改动是通过增加新代码进行的,而不是更改现有的代码这就是「开放-封闭原则」的精神所在。

你应该大胆尝试,在每一次尝试时都开新的坑,去犯新的错,然后通过迭代慢慢来完善。成为一个专业的软件开发者的过程就是不断积累后悔和「 error check list 」 的过程。你从「 Run Success 」身上学不到任何东西,知道优质代码长什么样,作用也微乎其微,你需要的是:对垃圾代码记忆犹新。

Perlis 也说过:

In programming, as in everything else, to be in error is to be reborn.

同时敢不敢写垃圾代码,完全取决于心态。写程序其实有两种心态,一种是做 Demo 的心态,一种是做项目的心态。让我们来对比下这两个心态:

两种状态

对于业务逻辑,垃圾代码有时候是更好的选择,否则极小的封装都可以将你再次带入「过度封装」的陷阱。业务逻辑是那种有着无尽的 if else 、边界情况和快速而 dirty 的 hack 的代码。

现在你再回过头来思考下:一大坨垃圾代码,和过度封装的业务逻辑代码,哪个更好?

有时候删掉一个大的错误比删掉 18 个彼此相关联的小错误更为容易。

摒弃代码洁癖,拥抱合理的冗余

冗余一样被贴着「垃圾代码」的标签,难道冗余就没有一点好处?你必须试着拥抱合理的冗余。

我们会通过复制和粘贴来将部分代码重复使用以避免引入依赖性,提高灵活度,但代价就是冗余。

「一坨代码被使用两次,就应该封装」这个论调不应该被提倡。往往是刚开始很方便,越往后,随着需求的变更,越成为一种累赘。 为了一个小功能就去写一个库,甚至这个库只有一个方法,这样会带来什么问题?你削减了使用到了这个库的所有模块之间的独立性,这样做毫无必要。

想写优质代码,要学会如何不写代码

代码越少, Bug 越少,代码也就越优质。

正如 iOS Architecture Patterns 这篇博客所言:

The less code you have, the less bugs you have.

The best code is the code that has never been written.

你应该始终明白什么是最优雅的解决方式。

为第三方库写工具类、模板类

我们构建模块不是为了复用,而是为了易于修改。

建工具类,出于两个完全相反的原因:低耦合、紧耦合。

低耦合

上面提到的「 ASI 切换 AFN 」教会我们:要为第三方库封装。尽量不要直接使用第三方库,而是为它们封装一层,通常我们叫这些类 Tool 、 Handler 、 Helper 、 Manager (先不吐槽命名了)。考虑到的是替换需求,由第三方库而衍生出来的工具类,通常也放在叫 Tool 的文件夹下。这样做的目的是尽可能将变化频繁的部分和相对更稳定的部分隔开来实现低耦合。这也同样适用于数据库以及各种可能会变更的 UI 组件。

紧耦合

但也不要一味追求「低耦合」,要根据实际情况来选择「紧耦合 tight coupling 」。比如错误处理就是一个需要与项目紧密结合在一起的操作。这个紧耦合的部分,我们就要放到 Tool 里,这也是建 Tool 的另一要考虑的原因:库总是试图迎合所有的需求,而我们只会用到其中小部分功能,而且只会对相应的响应做出特定的处理。所以建工具类可以隐藏不必要的细节。

好的 API 总是大而全,而建 Tool 则是我们意识到我们不能同时让所有人都高兴。开发一个好用的 API 和开发一个具有扩展性的 API 通常是互相冲突的。Tool 的作用就是让他们好用。

造轮子

你在建 Tool 时应该已经体会到紧耦合的好处了,但有时 Tool 已经完全满足不了我们的紧耦合需求,这时我们就需要造轮子。

iOS 里 Star 数最多的一个库是 AFNetworking ,为什么?当年 iOS 5 、 iOS 6 时代还没有 NSURLSession 的时候, NSURLConnection 做断点续传和断点下载是非常困难的,而且苹果的 API 不对外隐藏任何细节,这也就造就了 AFNetworking ——它为大家隐藏了很多细节,所以好用。

同样的道理,在日益复杂化的 App 开发中, Auto layout 逐渐成为最佳选择。但复杂的 VFL 语法,以及开发者不太买账的 Storyboard 、 XIB 可视化操作,也成就了 Masorny 。 Masorny 以其优雅的链式纯代码操作,渐渐成为自动布局的主流框架。

设计模式的「单一责任」原则告诉我们:

每一个模块都应该只去解决一个难题

但我们更需要:

每一个难题都只应该由一个模块去解决

当一个问题需要两个模块去做的时候,通常都是因为改变一部分需要另外一部分的改变。

一个写得很糟糕但是有着简单接口的组件,通常比需要互相协调的两个组件更容易使用。

你应该像 AFNetworking 、 Masorny 那样,写出这样的优质代码:能将写起来、维护起来,或者删除起来最困难的部分互相隔离开。

如何参与「壹期壹问」?

大家可以通过问题提交通道来向 LeanCloud 提问。