重构-提升代码质量

1.去除重复代码

2.去除过长函数

一个函数如果需要花时间才能搞懂就需要将其提炼

(一个函数不超过80行)

3.数据泥团

(当有多个参数互相搭配,某些数据成群出现(关联性极高),可以将其封装成一个数据对象)

4.封装全局变量

(用get,set来控制避免误触)

// 封装变量操作 good
let globalData = 1
function getGlobalData() {
  return globalData
}

function setGlobalData(newGlobalData){
  if (!isValid(newGlobalData)) {
    throw Error('Illegal input!!!')
    return
  }
  
  globalData = newGlobalData
}
// 暴露方法
export {
  getGlobalData,
  setGlobalData
}

5.发散式变化:

函数复合多方向的功能时要将其拆开

function getPrice(order) {
  // 获取基础价格
  const basePrice = order.quantity * order.itemPrice
  // 获取折扣
  const quantityDiscount = Math.max(0, order.quantity - 500) * order.itemPrice * 0.05
  // 获取运费
  const shipping = Math.min(basePrice * 0.1, 100)
  // 计算价格
  return basePrice - quantityDiscount + shipping
}

const orderPrice = getPrice(order);


// 计算基础价格
function calBasePrice(order) {
    return order.quantity * order.itemPrice
}
// 计算折扣
function calDiscount(order) {
    return Math.max(0, order.quantity - 500) * order.itemPrice * 0.05
}
// 计算运费
function calShipping(basePrice) {
    return Math.min(basePrice * 0.1, 100)
}
// 计算商品价格
function getPrice(order) {
    return calBasePrice(order) - calDiscount(order) + calShipping(calBasePrice(order))
}

const orderPrice = getPrice(order)

6.霰弹式修改:

与发散式修改相反,同一方向的功能被分散时要将其复合

7.去除for

用filter、map替换

8.复杂的条件逻辑&&合并条件表达式

将过于  复杂的条件/或变量  化为函数

// bad
if (!date.isBefore(plan.summberStart) && !date.isAfter(plan.summberEnd)) {
  charge = quantity * plan.summerRate
} else {
  charge = quantity * plan.regularRate + plan.regularServiceCharge
}


// good
if (isSummer()) {
  charge = quantity * plan.summerRate
} else {
  charge = quantity * plan.regularRate + plan.regularServiceCharge
}

// perfect
isSummer() ? summerCharge() : regularCharge()

9.查询函数与修改函数耦合

10.依恋情结:两个类频繁交互,可以将其所频繁交互处合并

11.基本类型偏执:

对于一个基本类型被用于各种转换计算输出不同格式,可以将其创建一个自己的基本类型

12.重复的switch:

对于switch重复出现,可提取相同元素,构建子类

13.夸夸其谈通用性

系统里存在一些 夸夸其谈通用性 的设计,常见语句就是 我们总有一天会用上的,并因此企图以各式各样的钩子和特殊情况来处理一些非必要的事情。

比如A() B().A只是调用B的功能,美其名曰A之后有大用

14.临时字段

由于“aCustomer === 'unknown' 这是个特例情况,在这个特例情况下,就会使用到很多临时字段,或者说是特殊值字段。这种重复的判断不仅会来重复代码的问题,也会非常影响核心逻辑的代码可读性,造成理解的困难。”

class Site {
  constructor(customer) {
    this._customer = customer;
  }

  get customer() {
    return this._customer;
  }
}

class Customer {
  constructor(data) {
    this._name = data.name;
    this._billingPlan = data.billingPlan;
    this._paymentHistory = data.paymentHistory;
  }

  get name() {
    return this._name;
  }
  get billingPlan() {
    return this._billingPlan;
  }
  set billingPlan(arg) {
    this._billingPlan = arg;
  }
  get paymentHistory() {
    return this._paymentHistory;
  }
}

// Client 1
{
  const aCustomer = site.customer;
  // ... lots of intervening code ...
  let customerName;
  if (aCustomer === 'unknown') customerName = 'occupant';
  else customerName = aCustomer.name;
}

// Client 2
{
  const plan = aCustomer === 'unknown' ? registry.billingPlans.basic : aCustomer.billingPlan;
}

// Client 3
{
  if (aCustomer !== 'unknown') aCustomer.billingPlan = newPlan;
}

// Client 4
{
  const weeksDelinquent = aCustomer === 'unknown' ? 0 : aCustomer.paymentHistory.weeksDelinquentInLastYear;
}

这里,我要把所有的重复判断逻辑都移除掉,保持核心逻辑代码的纯粹性。然后,我要把这些临时字段收拢到一个地方,进行统一管理。只在初始化时进行判断

class NullCustomer extends Customer {
  constructor(data) {
    super(data);
    this._name = 'occupant';
    this._billingPlan = { num: 0, offer: 0 };
    this._paymentHistory = {
      weeksDelinquentInLastYear: 0
    };
  }
}

// initial.js
const site = customer === 'unknown' ? new Site(new NullCustomer()) : new Site(new Customer(customer));

// Client 1
{
  const aCustomer = site.customer;
  // ... lots of intervening code ...
  const customerName = aCustomer.name;
}

// Client 2
{
  const plan = aCustomer.billingPlan;
}

// Client 3
{
}

// Client 4
{
  const weeksDelinquent = aCustomer.paymentHistory.weeksDelinquentInLastYear;
}

15.内幕交易

有强依赖关系的两个类

“在这个案例里,如果要获取 Person 的部门代码 code 和部门领导 manager 都需要先获取 Person.department。这样一来,调用者需要额外了解 Department 的接口细节,如果 Department 类修改了接口,变化会波及通过 Person 对象使用它的所有客户端。”

这种情况可直接将后者合并至前者

class Person {
  constructor(name) {
    this._name = name;
  }
  get name() {
    return this._name;
  }
  get department() {
    return this._department;
  }
  set department(arg) {
    this._department = arg;
  }
}

class Department {
  get code() {
    return this._code;
  }
  set code(arg) {
    this._code = arg;
  }
  get manager() {
    return this._manager;
  }
  set manager(arg) {
    this._manager = arg;
  }
}
class Person {
  constructor(name, department) {
    this._name = name;
    this._department = department;
  }
  get name() {
    return this._name;
  }
  get departmentCode() {
    return this._department.code;
  }
  set departmentCode(arg) {
    this._department.code = arg;
  }
  get manager() {
    return this._department._manager;
  }
  set manager(arg) {
    this._department._manager = arg;
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值