Clean Code小结

  1. 使用有准确意义的变量名

  2. 在变量值不会改变时使用const声明一个常量

  3. 对同一类型的变量使用相同的词汇

  4. 使用可搜索的名称(用var声明全局的大写变量)

  5. 使用解释型的变量

bad:

const cityStateRegex = /^(.+)[,\\s]+(.+?)\s*(\d{5})?$/;
saveCityState(cityStateRegex.match(cityStateRegex)[1], cityStateRegex.match(cityStateRegex)[2]);

good:

const cityStateRegex = /^(.+)[,\\s]+(.+?)\s*(\d{5})?$/;
const match = cityStateRegex.match(cityStateRegex)
const city = match[1];
const state = match[2];
saveCityState(city, state);
  1. 短路语法比条件语句更清晰
  2. 函数参数理论上少于等于2个
  3. 一个函数只做一件事
  4. 函数名称要说明他做的事
  5. 函数应该只抽象一个层次
  6. 删除重复代码
  7. 使用默认参数代替短路表达式

bad:

function writeForumComment(subject, body) {
  subject = subject || 'No Subject';
  body = body || 'No text';
}

good:

function writeForumComment(subject = 'No subject', body = 'No text') {
  ...
}
  1. 用Object.assign设置默认对象
config = Object.assign({
    title: 'Foo',
    body: 'Bar',
    buttonText: 'Baz',
    cancellable: true
  }, config);
  1. 不要把标记用作函数参数(Boolean值)

bad:

function createFile(name, temp) {
  if (temp) {
    fs.create('./temp/' + name);
  } else {
    fs.create(name);
  }
}

good:

function createTempFile(name) {
  fs.create('./temp/' + name);
}

function createFile(name) {
  fs.create(name);
}
  1. 避免否定条件
  2. 封装条件

bad:

if (fsm.state === 'fetching' && isEmpty(listNode)) {
  /// ...
}

good:

function shouldShowSpinner(fsm, listNode) {
  return fsm.state === 'fetching' && isEmpty(listNode);
}

if (shouldShowSpinner(fsmInstance, listNodeInstance)) {
  // ...
}
  1. 避免副作用

函数参数名和全局变量一样时,将全局变量置于函数之后
18. 喜欢上命令式编程之上的函数式编程

bad:

const programmerOutput = [
  {
    name: 'Uncle Bobby',
    linesOfCode: 500
  }, {
    name: 'Suzie Q',
    linesOfCode: 1500
  }, {
    name: 'Jimmy Gosling',
    linesOfCode: 150
  }, {
    name: 'Gracie Hopper',
    linesOfCode: 1000
  }
];

var totalOutput = 0;

for (var i = 0; i < programmerOutput.length; i++) {
  totalOutput += programmerOutput[i].linesOfCode;
}

good:

const programmerOutput = [
  {
    name: 'Uncle Bobby',
    linesOfCode: 500
  }, {
    name: 'Suzie Q',
    linesOfCode: 1500
  }, {
    name: 'Jimmy Gosling',
    linesOfCode: 150
  }, {
    name: 'Gracie Hopper',
    linesOfCode: 1000
  }
];

var totalOutput = programmerOutput
  .map((programmer) => programmer.linesOfCode)
  .reduce((acc, linesOfCode) => acc + linesOfCode, 0);
  1. 避免条件
  2. 避免类型检查
  3. 不要过度优化

bad:

for (var i = 0, len = list.length; i < len; i++) {
  // ...
}

good:

for (var i = 0; i < list.length; i++) {
  // ...
}
  1. 删除不用的代码(不要注释代码)
  2. 使用getter和setter

bad:

class BankAccount {
  constructor() {
       this.balance = 1000;
  }
}

let bankAccount = new BankAccount();

// 支出
bankAccount.balance = bankAccount.balance - 100;

good:

class BankAccount {
  constructor() {
       this.balance = 1000;
  }

  // It doesn't have to be prefixed with `get` or `set` to be a getter/setter
  withdraw(amount) {
    if (verifyAmountCanBeDeducted(amount)) {
      this.balance -= amount;
    }
  }
}

let bankAccount = new BankAccount();

bankAccount.withdraw(100);

  1. 让对象拥有私有成员(通过函数return)

bad:

var Employee = function(name) {
  this.name = name;
}

Employee.prototype.getName = function() {
  return this.name;
}

var employee = new Employee('John Doe');
console.log('Employee name: ' + employee.getName()); // Employee name: John Doe
delete employee.name;
console.log('Employee name: ' + employee.getName()); // Employee name: undefined

good:

var Employee = (function() {
  function Employee(name) {
    this.getName = function() {
      return name;
    };
  }

  return Employee;
}());

var employee = new Employee('John Doe');
console.log('Employee name: ' + employee.getName()); // Employee name: John Doe
delete employee.name;
console.log('Employee name: ' + employee.getName()); // Employee name: John Doe
  1. 类-单一职责原则(SRP)
  2. 开放封装原则(OCP)
  3. 里氏替换原则(LSP)
  4. 接口隔离原则(ISP)
  5. 依赖倒置原则(DIP)
  6. async/await

bad:(promise)

require('request-promise').get('https://en.wikipedia.org/wiki/Robert_Cecil_Martin')
  .then(function(response) {
    return require('fs-promise').writeFile('article.html', response);
  })
  .then(function() {
    console.log('File written');
  })
  .catch(function(err) {
    console.error(err);
  })

good:

async function getCleanCodeArticle() {
  try {
    var request = await require('request-promise')
    var response = await request.get('https://en.wikipedia.org/wiki/Robert_Cecil_Martin');
    var fileHandle = await require('fs-promise');

    await fileHandle.writeFile('article.html', response);
    console.log('File written');
  } catch(err) {
      console.log(err);
    }
  }
  1. 错误处理
try {
  functionThatMightThrow();
} catch (error) {
  // 选择之一(比 console.log 更闹心):
  console.error(error);
  // 另一个选择:
  notifyUserOfError(error);
  // 另一个选择:
  reportErrorToService(error);
  // 或者所有上述三种选择!
}

  1. 使用一致的大小写
  2. 调用者和被调用者尽可能的放在一起
  3. 删除已注释代码及尽量少使用注释
  4. 做有意义的区分,依义命名

不要使用如a1,a2,a3…这样没有区分度的命名,用parent,children等有意义的区分
36. 不要使用双关语

如add,使用append或insert这类动词
37. 变量,函数,类的命名应该尽量简短,有具体意义(data,info都是一个意思)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值