真正优质的代码具有什么条件?如何高效的编写优质代码?——来自用户 yuklngphp
优质的代码基本的条件:轻量级、低耦合(松耦合)、易替换、易删除。html
什么叫低耦合?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 的心态,一种是作项目的心态。让咱们来对比下这两个心态:
<img src="https://blog.leancloud.cn/wp-content/uploads/2016/04/c6fc633cc3da8f1aa3d73a755e84b53b-625x607.png" alt="两种状态" width="625" height="607" class="alignnone size-medium wp-image-4514" />
对于业务逻辑,垃圾代码有时候是更好的选择,不然极小的封装均可以将你再次带入「过分封装」的陷阱。业务逻辑是那种有着无尽的 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 五、iOS 6 时代尚未 NSURLSession 的时候,NSURLConnection 作断点续传和断点下载是很是困难的,并且苹果的 API 不对外隐藏任何细节,这也就造就了 AFNetworking——它为你们隐藏了不少细节,因此好用。
一样的道理,在日益复杂化的 App 开发中, Auto layout 逐渐成为最佳选择。但复杂的 VFL 语法,以及开发者不太买帐的 Storyboard、XIB 可视化操做,也成就了 Masorny。Masorny 以其优雅的链式纯代码操做,渐渐成为自动布局的主流框架。
设计模式的「单一责任」原则告诉咱们:
每个模块都应该只去解决一个难题
但咱们更须要:
每个难题都只应该由一个模块去解决
当一个问题须要两个模块去作的时候,一般都是由于改变一部分须要另一部分的改变。
一个写得很糟糕可是有着简单接口的组件,一般比须要互相协调的两个组件更容易使用。
你应该像 AFNetworking、Masorny 那样,写出这样的优质代码:能将写起来、维护起来,或者删除起来最困难的部分互相隔离开。
你们能够经过问题提交通道来向 LeanCloud 提问。