关于如何编写 Clean Code 的 6 个简单技巧

160

做者:Alex Deverojavascript

翻译:承香墨影java

编写简洁代码(Clean Code)不是一件很是容易的事情,为了保持代码整洁,你须要尝试不一样的技巧和作法。问题是,在这个问题上,有太多的作法和技巧,是须要大量的重构的。所以,开发者很难选择出适合本身项目的作法和技巧。程序员

让咱们来简化这个任务,在本文中,咱们将讨论编写整洁代码的一些好处,而后再来看看咱们总结的 6 个技巧和实践,以便让开发人员理解,编写 Clean Code 最常使用的一些技巧。算法

1、编写简洁代码的好处

让咱们先看看编写简洁干净的代码有什么好处。其中一个主要的好处是,简洁干净的代码能够帮助咱们最大限度的减小阅读和试图理解代码的时间。凌乱的代码风格,具备难以想象的能力,能够加大开发人员的工做效率,让它们的工做变的更加困难。代码越是混乱,开发人员维护起来须要的时间越多。并且,若是代码太乱,维护的开发人员可能会决定停下来,而后重构它。编程

1.1 更容易开始,也更容易继续

让我举一个简单的例子来讲明这一点。设计模式

假设咱们在很长一段时间以后,从新维护咱们以前开发的某一个项目。也许,是咱们之前的某个客户,联系了咱们并从新须要咱们对其进行继续的扩展与维护。函数

如今,咱们能够想像到,若是在项目开发阶段,咱们没有使用简洁代码的技巧编写简洁的代码,而是写下了相反的代码。你将第一次知道,你的代码是多么的糟糕和混乱。并且这个时候你会发现,从新维护一个以前的项目,是多么的艰难。学习

所以,咱们如今必须在这个项目上,花费更多的时间,由于咱们须要从新了解咱们以前编写的代码。而这并非必要的,咱们能够从一开始就坚持编写简洁代码,来彻底避免它。字体

如今咱们必须增长成本,并且,咱们的旧代码如此的混乱不堪,若是咱们决定从头开始。我想这不是你的客户们乐意听到的,由于这表明了成本的增长和工期的延长。优化

Clean Code 就不会有这样的问题,想像一下前面的例子,状况就会恰好相反。如今,咱们以前的代码是干净且优雅的。那咱们须要多长时间才能理解它?也许只须要几分钟,简单阅读一下代码,了解以前是如何工做的。最后咱们在这个基础上,花费一段时间进行维护或者扩展新的功能。此次投资的成本和时间,将会小得多,咱们的客户可能都不会注意到你作了什么。

这就是咱们讨论坚持使用 Clean Code 编码技巧的第一个好处。并且,这不只仅是为了咱们本身维护的项目,也是为了其余开发者。Clean Code 可以让咱们更快的上手,咱们或者其余开发者,都不须要花费数个小时的时间来研究它。咱们能够更快的进入到工做之中。

1.2 更容易让人加入团队

Clean Code 的另外一个好处是与第一个缘由密切相关的,它将加快新人接手项目的速度。

个人意思是,假设咱们须要聘请另一个开发人员,须要多长时间才能理解代码并学习如何使用它?这取决于,若是咱们的代码自己很混乱,写的很差,他将须要更多的时间来完成首次接手的工做。而若是咱们的代码是保持简洁的、易读的,这将很是的易于理解,那么他就能更快的接手而且开始编写新的需求。

有些人可能以为这不是一个问题,由于咱们还在这里,咱们能够帮助他更快的理解,虽然这真的能够加快他的上手速度。可是,咱们的帮助只应该花费咱们很短暂的时间,一两天或者三天,而不该该是一周或者很频繁的。

当咱们决定招募另外一位开发人员,是为了加速咱们的项目研发,而不是放缓它。咱们的目标不是帮助他学习如何在咱们以前编写的代码之上继续编码,这将会消磨咱们更多的时间。

1.3 更容易保持规范

有一件事情咱们须要注意,了解和学习如何编写代码是一回事。可是,这只是一个开始,咱们还须要确保开发者可以而且愿意遵循咱们的编码规范,并将它持续的实践在项目中。这将能保持项目是持续的干净整洁,而不会所以而凌乱下去。这一点很重要,由于咱们不只要编写简洁的代码,还要保持这样的代码,无论未来有多少人会来维护它,咱们须要长期坚持和思考这个问题。

最后,若是咱们团队的开发者之一,决定不遵循当前的编码规范呢?

一般这个问题会被自行解决。假设咱们有一群人在相同的项目代码上进行工做,而且开始偏离既定的代码规范。这可能会致使三个方向的发展。

首先,团队的其余成员会推进这名开发人员遵循标准,若是他不想离开团队,他会接收的。

第二个方向是,开发人员可以说服团队的其余成员采用并遵循他的编码规范。若是开发人员提出的编码规范是更简洁的,能带来更好的结果,这应该是一件好事情。编写并保持咱们的代码简洁,并不意味着咱们应该忽略任何改进它的机会。偏偏相反,咱们相信咱们老是应该质疑咱们目前的作法,并寻求改善的机会。

因此,若是一个开发者偏离了咱们的想法,并且他的作法更好,这样的状况下,咱们作出改变,多是最好的结果,而不是让他来改变。我认为,咱们审视和尝试以前,咱们不该该忽视别人的方法。事情总有改进的余地,咱们应该持续的寻找改进的方法,而不是固守成规。

最后一种也是咱们最不肯意看到的,开发者决定不采用咱们的规范,也不尝试说服咱们采用他的规范。这可能致使他离开团队。

2、编写 Clean Code 的一些建议

以前,咱们在讨论编写简洁代码的一些好处,如今是时候学习一些技巧来帮助咱们作到这一点。

正如咱们将要看到的,拥抱简洁的代码并遵循这些建议进行实践下去。这些咱们总结的作法,会使咱们的代码更加清晰、可读,更简单而且易于理解。

固然,你并不须要实践这些全部的建议,实践而且遵循一两个,就足以代码有效的成果。

2.1 让代码可读

是的,咱们编写的代码,最终会被机器解释。可是,这并不意味着咱们应该忽略它的可读性和可理解性。总会有另外的开发者有机会阅读咱们的代码,否者将没法维护它。即便做为独立开发者坚持本身维护代码,咱们也可能会在未来继续维护咱们的项目。出于这些缘由,咱们应该保持咱们代码的可读性。

最简单的方法是使用空格进行格式化,咱们在发布代码以前,将代码压缩(混淆)是能够的。可是咱们并不须要编写看起来像是被压缩的代码。相反,咱们可使用缩进、换行和空行,来使代码的结构更具备可读性。当咱们决定采起这个作法的时候,咱们代码的可读性和可理解性能够显著提升。

接下来,看一下咱们的示例代码,就应该可以理解它了。

Code1:

// Bad
const userData=[{userId: 1, userName: 'Anthony Johnson', memberSince: '08-01-2017', fluentIn: [ 'English', 'Greek', 'Russian']},{userId: 2, userName: 'Alice Stevens', memberSince: '02-11-2016', fluentIn: [ 'English', 'French', 'German']},{userId: 3, userName: 'Bradley Stark', memberSince: '29-08-2013', fluentIn: [ 'Czech', 'English', 'Polish']},{userId: 4, userName: 'Hirohiro Matumoto', memberSince: '08-05-2015', fluentIn: [ 'Chinese', 'English', 'German', 'Japanese']}];

// Better
const userData = [
  {
    userId: 1,
    userName: 'Anthony Johnson',
    memberSince: '08-01-2017',
    fluentIn: [
      'English',
      'Greek',
      'Russian'
    ]
  }, {
    userId: 2,
    userName: 'Alice Stevens',
    memberSince: '02-11-2016',
    fluentIn: [
      'English',
      'French',
      'German'
    ]
  }, {
    userId: 3,
    userName: 'Bradley Stark',
    memberSince: '29-08-2013',
    fluentIn: [
      'Czech',
      'English',
      'Polish'
    ]
  }, {
    userId: 4,
    userName: 'Hirohiro Matumoto',
    memberSince: '08-05-2015',
    fluentIn: [
      'Chinese',
      'English',
      'German',
      'Japanese'
    ]
  }
];

code:

// Bad
class CarouselLeftArrow extends Component{render(){return ( <a href="#" className="carousel__arrow carousel__arrow--left" onClick={this.props.onClick}> <span className="fa fa-2x fa-angle-left"/> </a> );}};

// Better
class CarouselLeftArrow extends Component {
  render() {
    return (
      <a
        href="#"
        className="carousel__arrow carousel__arrow--left"
        onClick={this.props.onClick}
      >
        <span className="fa fa-2x fa-angle-left" />
      </a>
    );
  }
};

2.2 为变量、方法取有意义的名称

再让咱们来看看第二个技巧,这将帮助咱们编写易于理解的代码。

这个技巧是关于变量、函数和方法使用有意义的名称。有意义是什么意思?有意义的名称是具备描述性的名称,不只仅是咱们,其余人也可以看名称就能理解,这些变量、函数和方法的目的。

换句话说,名称自己应该就能够提示变量、函数和方法的用途,或者它包含的内容。

接下来看个例子。

// Bad
const fnm = ‘Tom’;
const lnm = ‘Hanks’
const x = 31;
const l = lstnm.length;
const boo = false;
const curr = true;
const sfn = ‘Remember the name’;
const dbl = [‘1984’, ‘1987’, ‘1989’, ‘1991’].map((i) => {
  return i * 2;
});

// Better
const firstName = ‘Tom’;
const lastName = ‘Hanks’
const age = 31;
const lastNameLength = lastName.length;
const isComplete = false;
const isCurrentlyActive = true;
const songFileName = ‘Remember the name’;
const yearsDoubled = [‘1984’, ‘1987’, ‘1989’, ‘1991’].map((year) => {
  return year * 2;
});

可是,咱们应该知道,使用描述性名称并不意味着咱们能够自由使用尽量多的单词来描述它。一个好的经验法则是将名称限制在三个或者四个单词。若是咱们须要四个以上的单词才能描述它,这也许是由于咱们一次尝试让它作太多的事情,这个时候咱们应该简化咱们的代码,而不是坚持使用它。

2.3 让一个函数或者方法,只执行一个任务

当我开始写代码的时候,我曾经写过相似瑞士军刀的功能和方法。它们能够处理和作任何事情。可是到了后期,其中的一个后果就是很难再找到一个好名字来扩展它。其次,除了我以外,几乎没有人知道这个和那个功能是什么以及如何使用它,有时候我本身也会面临这个问题,因此我不得不写下注释。第三,这些功能是不可预测的,而我所以写了一段混乱的代码。

而后,有人给了一个伟大的建议,让每一个功能或方法只执行一项任务。这个简单的建议改变了一切,并帮助我编写简洁的代码,至少比以前更加干净简洁。从那一刻开始,其余人终于可以理解个人代码了。或者说,他们不须要像之前同样,花费那么多的时间来理解个人代码。个人功能和方法也变得可预测。在相同的输入下,它们老是产生相同的输出。并且,命名也变得更容易。

若是你很难为你的函数和方法找到描述性名称,或者你须要编写冗长的注释以便其余人可使用它们,请考虑实时单一职责。让每一个函数或方法只执行一项任务。若是你的函数和方法看起来像瑞士军刀同样大而全,也能够实施这种作法。相信我,在编写代码上,任何多功能性都不是一个优点。任什么时候候均可能会致使拔苗助长的效果,这是一个至关不利的因素。

注意:让每一个函数或方法只执行一项任务的作法称为单一责任原则。罗伯特·C·马丁(Robert C. Martin)将这种编码实践做为五种面向对象设计原理之一(也称为SOLID)进行了介绍。

// Example no.1: 简单的减法
function subtract(x, y) {
    return x - y;
}
// Example no.1: 简单的乘法
function multiply(x, y) {
    return x * y;
}

// Example no.1: Double numbers in an array
function doubleArray(array) {
  return array.map(number => number * 2)
}

2.4 写好注释

无论咱们为本身的变量,函数和方法,绞尽脑汁的相处有意义的名称。咱们的代码自己可能仍是有一些不清晰或者不易于理解的地方。多是有一些逻辑分支须要单独解释,这些可能不是它们很难理解和使用的缘由。相反可能只是一些历史遗留问题。

有时咱们可能不得不采起很是规的方式来解决问题,由于没有别的办法可行,或者咱们没有足够的时间来提出更好的解决方案。

这可能很难用代码解释。经过在咱们的代码中,增长注释能够帮助咱们解决这个问题。注释能够帮助咱们向其余人解释为何咱们写了这段不合规的代码,以及我面临的问题和现状。所以,其余人在阅读的时候就很清晰,没必要猜想个人当时的想法。

更重要的是,当咱们解释咱们的缘由时,其余人可能会找到一个更好的方法来解决问题并改进代码。这是可能的,由于他们可能知道问题是什么,指望的结果是什么。若是不知道这些信息,其余人就难以创造更好的解决方案。否者,其余人将不会尝试优化解决它,由于他们不认为有这个须要,他们可能认为这就是咱们真实的想法。

因此,当咱们发现本身处于一种咱们决定使用一些很是规的方式,快速修复或绕过问题方法的来解决问题状况下,咱们就应该用注释来解释为何咱们面临的是什么问题,为何要这么作。用一两行注释来解释它比强迫其余人猜想更好。

也就是说,咱们应该只在有必要时才使用注释,而不是解释错误的代码。不停的增长注释,并不会帮助咱们将写得差的代码转换成干净简洁的代码。若是代码很差,咱们应该经过改进代码来解决问题,而不是经过添加关于如何使用代码的注释。简洁的代码优先于使用注释解释。

2.5 保持一致

当咱们找到咱们喜欢的具体的编码实践或风格时,咱们应该坚持并在任何地方使用它。在不一样的项目中使用不一样的编码规范或样式不是一个好主意。它几乎与不使用任何编码规范或风格同样无用。这将致使,回到咱们的旧代码将不会如此平稳和天然。咱们仍然须要一些时间来理解咱们在该项目上使用的编码规范,而后才能使用它。

最好的办法是挑选一套编码规范,而后在咱们全部的项目中坚持这些规范。那么,回到咱们之前的代码会更容易,并继续咱们中止或改进的地方。尝试新的编码规范是一件好事。它能够帮助咱们找到更好的方式来完成咱们的工做。

可是,在挑选编码规范的时候,咱们应该多作一些尝试,而且实际使用在多个地方。咱们应该花精力去验证咱们的规范,来保证它整的适合咱们,只有在咱们对此感到满意的时候,咱们才应该实施它。而且在所有项目中,使用这套规范。

2.6 定义检查代码,适时重构

这是我编写干净的代码的最后一个技巧。

简单地写简洁的代码并非一切。咱们的工做并不由于咱们使用了简洁的风格编写代码而结束。下一步是保持咱们的代码的简洁。简洁的代码须要维护,当咱们写代码的时候,咱们应该按期回视检查,清理垃圾代码并进行改进。不然,若是咱们不检查和更新旧代码,它很快就会过期。就像咱们的硬件设备同样。若是咱们想要保持最佳状态,咱们须要按期更新它们。

对于咱们天天使用的代码来讲,状况尤为如此。代码有变得愈来愈复杂和混乱的趋势,而不是简单和整洁。咱们要防止这种状况发生,并保持咱们的代码的简洁。要作到这一点的惟一方法是按期检查咱们的代码。换句话说,咱们须要维护它。对于咱们再也不关心或没有前途的项目来讲,这可能不是必要的。对于其重要的项目来讲,维护是咱们工做的一部分。

3、关于编写 Clean Code 的总结

这篇文章到此就要结束了。

咱们今天讨论的这六种作法可能不是那些影响最大或效果最显着的作法。可是,他们是经验丰富的开发人员最常提到的。这就是我选择他们的缘由。我但愿这些实践或技巧足以帮助你开始编写干净的代码。

如今,像全部事情同样,最重要的是开始。因此,选择至少一个练习,并尝试一下。

英文原文地址:

https://hackernoon.com/6-simp...

今天在承香墨影公众号的后台,回复『成长』。我会送你一些我整理的学习资料,包含:Android反编译、算法、设计模式、虚拟机、Linux、Web项目源码。

推荐阅读:

相关文章
相关标签/搜索