如何让你的 PHP 代码保持整洁?
我坐在我的公位上,和我的团队成员一起解决问题。我说:“我们必须搞定它”,把自己深深的埋在开发一个工作原型的两天里 - 竞争的本质在每个人的心中被点燃,我们必须争夺第一,第二,和第三。
几分钟后,其中一位高级工程师走到我的办公桌前,脸上一副不满的神情,喃喃地说:“你的代码不整洁,太乱了! 这就是我走向一个更干净整洁的代码的开始。
代码能跑起来不就完了嘛,还要整洁?你可能会听到有人这么说,但我要说的是,代码不仅要能跑起来,还要写整洁,真的。
我当一名软件工程师有几年了,写了一些程序。这段岁月告诉我,代码仅能跑起来是不够的。
我的问题很简单:我专注于让代码跑通了,可招致了技术性债务,而这些债务在某个时刻将不得不还清。
如何让你的代码保持整洁
它不会发生那一刻你读完所有的章节(干净代码)(https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882)鲍勃叔叔。它需要知识和不断的实践,你必须学习原则、模式和实践。这是一件艰苦的工作,需要数年的时间,但你可以从今天开始。
不管你的程序员多么干净,总有一两件事情可以让你变得更干净。
最好的学习方法之一是通过阅读他们的书籍或文章来学习。你应该让他们的twitter消息流到你的twitter消息流中,倾听他们的谈话,在GitHub上跟踪他们,学习并学习他们的代码是如何编写和组织的。
如果你不经常从你所在领域的专家那里学习,你的成长是有限的。
保持你的功能小
这可能是1337篇文章中的一篇,强调尽可能短地保存方法或函数。这里很容易出错。
干净的代码不仅仅是编写简短的方法,更重要的是编写清晰地传达意图的代码。
当一个函数太长时,它可能表明它做得太多,读者可能会丢失解码它所做的事情,函数应该做一件事。
if($order->contains($status){
//do something with order
}
function contains($status){
$order_statuses=['accepted','delivered','rejected','processed'];
if (in_array($status, $order_statuses)) {
return true;
}
return false;
}
我们可以通过重写函数,使它'包含'整洁:
function contains($status){
return in_array($status, $this->config->statuses);
}
这个函数不仅'包含'干净,而且还耦合。
变量或函数的名字应该能够一眼看出它的作用
选择一个合适的函数名字有的时候可能很乏味,但是毫无疑问的是这值得你这样做!因为这使你在代码变更的时候不需要更新代码的注释!
$date =date('Y-m-d'); //当然,这是一个日期,但是他的命名太通用(可以代表很多东西)了
$orderCreationDate =date('Y-m-d'); // 整洁的代码
避免 if
和 switch
语句
个人认为,它(if
和 switch
语句)会让我花一点时间去理解。“你告诉我,我该怎么避免使用我最爱的语句之一——if & else?”事实证明,大部分条件语句可以简单的被分解成函数或类。这并不是说不让你使用 if
和 switch
语句,只是想说看情况使用!
这里有一个很好的例子:
class BookOrder
{
public function process()
{
switch ($this->book->type) {
case 'audiocopy':
return $this->processAudioBook();
break;
case 'downloadablecopy':
return $this->processDownloadableCopy();
break;
case 'paperbookcopy':
return $this->processPaperBookCopy();
break;
default:
}
}
}
一个干净且更易于维护的书写方式应该是这样的:
interface IBookOrder {
public function process();
}
class AudioBookOrder implements IBookOrder :void {
public function process()
{
// TODO: Implement process() method.
}
}
class PaperBookOrder implements IBookOrder: void {
public function process()
{
// TODO: Implement process() method.
}
}
class DownloadableBookOrder implements IBookOrder: void {
public function process()
{
// TODO: Implement process() method.
}
}
避免心理地图式命名
干净的代码应该易于阅读,理解,不应该有猜测的余地。
使程序看起来简单的不是语言,而是使语言变得简单的程序员。
Robert C. Martin
下面的代码检查客户是否可以提取一定数量的钱。这很有效,但很混乱。
if($this->user->balance > $amount && $this->user->activeLoan===0){
$this->user->balance -=$amount; // withdraw amount;
}
让我们把它弄的整洁一点
if($this->hasNoActiveLoan() && $this->canWithdrawAmount($amount)){
$this->withdraw($amount);
}
public function hasNoActiveLoan(){
return $this->user->activeLoan===0;
}
public function canWithdrawAmount(float $amount){
return $this->user->balance > $amount;
}
public function withdraw(float $amount){
$this->user->balance -=$amount;
}
这不仅容易理解,而且更容易测试。
理解和应用S.O.L.I.D的原则
S.O.L.I.D是Robert C Martin定义的面向对象编程的前五项原则的首字母缩略词。 这些原则在使用时,允许您编写低耦合,内聚和封装好的代码。 原则是密切相关的,只有它成功的应用可以帮助你编写更好的代码。 我会保存这个另一个职位,但你可以阅读这些原则 here.
不要对自己太苛刻
想知道为什么这在名单上吗? 在干净的代码世界中很容易脱离困境,并且想在一天之内吸收所有的东西。 可悲的消息是:这需要时间,几个月,几年和奉献。 这些原则必须学习和实践,但一切都始于决定让所有事情变得更加简单。
结论
通过写这篇文章, 我希望可以鼓励一些人做一个更好的开发者并且开始关心代码整洁 (万一你不是呢).
随时删除你的意见, 使例子变得简洁,可以在 LinkedIn ](https://www.linkedin.com/in/samuel-james-a... tell me about a new opportunity添加我.
进一步阅读
Awesome Curated List of Clean Code Resources\
Clean Code: A Handbook of Agile Software Craftsmanship 1st Edition\
Clean Code PHP\
A month of clean code\
Clean code concept adapted for PHP\
Clean code JavaScript
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
感觉中心思想就是提取方法
化整为零吧
强烈推荐大家去读英语原文和评论以及博主的其他文章,一定会产生很多新的认识。
对于用多态代替if...swich这块,只有实现,但是怎么应用。。。。。
是不是很笨啊
方便别人,方便自己~
@Edwin 化整为零是删库跑路么???
@xhh110 :smile:结构简单化
用现在流行的一个词汇就是去中心化 :smile:
没有人问一下吗?那我就问了 >_<
有没有译者做个备注,该怎么使用?分解成多个类之后,就不用 if,else了?
你不得判断用哪个类?
难道就不用判断了?
或者用动态拼接类名?那不现实啊,你能动态拼接类名肯定就能拼接方法名。
减少 if else?我觉得这个是让代码逻辑更清楚一点吧?把代码分得更细化。
@skyEvyn 我也想问这个问题,既然将switch改成了多态,但是用的时候呢,该怎么使用,不也是要 if 判断然后实例化不同的类然后进行方法调用吗?我实在看不出来这样写怎么方便,请知道的兄弟指教一下咯
@DavidNineRoc 对头,我也想问这个问题,这个文章只是讲如何封装,但是并没有解释如何怎么使用
@一根毛毛闯天下 倒是通过类名简单的知道要做什么了,不用 if else 感觉只能动态拼接类名了。
@DavidNineRoc 而且每一个判断都要先 new 一次然后再调用方法,这样内存就要分配一个地址空间出来,感觉会更占内存啊
@一根毛毛闯天下 不用判断,动态拼接类名,统一调用方法