侧边栏壁纸
博主头像
MicroMatrix博主等级

曲则全,枉则直,洼则盈,敝则新,少则得,多则惑。是以圣人抱一为天下式。不自见,故明;不自是,故彰;不自伐,故有功;不自矜,故长。夫唯不争,故天下莫能与之争。古之所谓“曲则全”者,岂虚言哉!诚全而归之。

  • 累计撰写 80 篇文章
  • 累计创建 21 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

如何优雅的避免代码嵌套

蜗牛
2024-01-30 / 0 评论 / 0 点赞 / 14 阅读 / 8327 字 / 正在检测是否收录...

避免过度代码嵌套是保持代码可读性和可维护性的关键步骤,特别是在编程中。以下是每一种方法,并附上在未优化代码和优化后代码的例子。

表驱动法

这种方法通过使用查找表替代复杂的条件语句来简化代码,减少嵌套。

未优化代码示例:

function calculateTax(income) {
  let tax;
  if (income < 20000) {
    tax = income * 0.1;
  } else if (income < 40000) {
    tax = income * 0.2;
  } else if (income < 80000) {
    tax = income * 0.3;
  } else {
    tax = income * 0.4;
  }
  return tax;
}

优化后的代码示例:

const taxBrackets = [
  { threshold: 80000, rate: 0.4 },
  { threshold: 40000, rate: 0.3 },
  { threshold: 20000, rate: 0.2 },
  { threshold: 0, rate: 0.1 }
];

function calculateTax(income) {
  const bracket = taxBrackets.find(bracket => income > bracket.threshold);
  return income * bracket.rate;
}

状态模式

状态模式允许对象在内部状态改变时改变它的行为。

未优化代码示例:

class Order {
  constructor() {
    this.state = 'Taking Order';
  }

  nextStage() {
    if (this.state === 'Taking Order') {
      this.state = 'Order Preparing';
    } else if (this.state === 'Order Preparing') {
      this.state = 'Order Ready';
    } else if (this.state === 'Order Ready') {
      this.state = 'Order Served';
    }
  }
}

优化后的代码示例:

class OrderState {
  next(order) {
    throw new Error('OrderState.next needs to be implemented');
  }
}

class TakingOrderState extends OrderState {
  next(order) {
    order.setState(new OrderPreparingState());
  }
}

class OrderPreparingState extends OrderState {
  next(order) {
    order.setState(new OrderReadyState());
  }
}

class OrderReadyState extends OrderState {
  next(order) {
    order.setState(new OrderServedState());
  }
}

class OrderServedState extends OrderState {
  next(order) {
    // Final state, no next state
  }
}

class Order {
  constructor() {
    this.state = new TakingOrderState();
  }

  setState(state) {
    this.state = state;
  }

  nextStage() {
    this.state.next(this);
  }
}

Lambda表达式

Lambda表达式可以减少匿名类的冗余代码。

未优化代码示例:

button.addActionListener(new ActionListener() {
  @Override
  public void actionPerformed(ActionEvent ae) {
    System.out.println("Button Pressed");
  }
});

优化后的代码示例:

button.addActionListener(ae -> System.out.println("Button Pressed"));

空值判断

使用Optional或者类似的可选类型可以避免深层次的空值检查。

未优化代码示例:

public String getCountry(User user) {
  if (user != null) {
    Address address = user.getAddress();
    if (address != null) {
      Country country = address.getCountry();
      if (country != null) {
        return country.getName();
      }
    }
  }
  return "Unknown";
}

优化后的代码示例:

public String getCountry(User user) {
  return Optional.ofNullable(user)
                 .map(User::getAddress)
                 .map(Address::getCountry)
                 .map(Country::getName)
                 .orElse("Unknown");
}

设计模式

使用设计模式可以提高代码的可读性和可维护性,比如策略模式可以避免条件语句。

未优化代码示例:

function calculateDiscount(items, type) {
  if (type === 'fixed') {
    return items * 10;
  } else if (type === 'percentage') {
    return items * 0.1;
  } else {
    return items;
  }
}

优化后的代码示例:

class DiscountStrategy {
  applyDiscount(items) {
    throw new Error('DiscountStrategy.applyDiscount needs to be implemented');
  }
}

class FixedDiscountStrategy extends DiscountStrategy {
  applyDiscount(items) {
    return items - 10;
  }
}

class PercentageDiscountStrategy extends DiscountStrategy {
  applyDiscount(items) {
    return items * 0.9;
  }
}

function calculateDiscount(items, strategy) {
  return strategy.applyDiscount(items);
}

// Usage:
const fixedStrategy = new FixedDiscountStrategy();
const percentageStrategy = new PercentageDiscountStrategy();
calculateDiscount(100, fixedStrategy);
calculateDiscount(100, percentageStrategy);

创建子函数

一个简单的技巧是将复杂函数拆解为多个子函数,这有助于减少嵌套层次。

未优化代码示例:

function processData(data) {
  if (data) {
    // 假设这里有10行处理 data 的代码
    if (data.hasDetail()) {
      // 又是一些复杂的处理
      if (data.detail.isComplete()) {
        // 处理完成
      }
    }
  }
}

优化后的代码示例:

function processDetail(detail) {
  if (detail.isComplete()) {
    // 处理完成
  }
}

function processData(data) {
  if (!data) {
    return;
  }
  // 简化的处理 data 的代码

  if (data.hasDetail()) {
    processDetail(data.detail);
  }
}

异步编程的优化

在JavaScript中,过度的嵌套通常出现在处理异步操作时,可以使用Promiseasync/await来减少嵌套。

未优化代码示例:

getData(function(a){
  getMoreData(a, function(b){
    getEvenMoreData(b, function(c){
      getSoMuchData(c, function(d){
        // 嵌套太深
      });
    });
  });
});

优化后的代码示例:

async function processData() {
  try {
    let a = await getData();
    let b = await getMoreData(a);
    let c = await getEvenMoreData(b);
    let d = await getSoMuchData(c);
    // 流程清晰
  } catch(error) {
    // 错误处理
  }
}

利用早期返回规避嵌套

早期返回意味着一旦满足特定条件就立即从函数返回,而不是继续进入下一层嵌套。

未优化代码示例:

function login(user) {
  if (user) {
    if (user.active) {
      if (checkPassword(user)) {
        // 登录成功
      } else {
        // 密码错误
      }
    } else {
      // 用户未激活
    }
  } else {
    // 用户不存在
  }
}

优化后的代码示例:

function login(user) {
  if (!user) {
    // 用户不存在
    return;
  }
  if (!user.active) {
    // 用户未激活
    return;
  }
  if (!checkPassword(user)) {
    // 密码错误
    return;
  }
  // 登录成功
}
0

评论区