25.如何优雅的避免代码嵌套?表驱动法 | 快乐路径 | 状态模式

博客介绍了三种编程相关方法。表驱动法可解决逻辑语句选择问题,选项增多时更易维护;快乐路径即提早返回,用于参数校验等,社区推荐使用单分支控制结构,符合相关原则;状态模式常用于审批流、状态流转等场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


代码地址: https://gitee.com/lymgoforIT/golang-trick/tree/master/16-avoid-multi-if

一:简介

相信大家在工作中都见过这么一条规范:如果你需要三层的嵌套,说明你的程序已经开始混乱,应该修复你的程序。

如下代码:(为了演示,故意没有使用&&运算)

// 职位
type JobPosition struct {
	salary       int64  // 薪资
	name         string // 职位名称
	workingHours string // 工作时长
}

func (j JobPosition) apply() {

}

// 申请一个合适的职位
func applyForSuitablePosition(positions []JobPosition) {
	for _, position := range positions {
		if position.salary > 1000 {
			if position.name == "super Engineer" {
				if position.workingHours == "996" {
					position.apply()
				}
			}
		}
	}
}

二:表驱动法

凡是可以通过逻辑语句来选择的事物,我们都可以通过查表法来解决,对于简单的情况,当然逻辑语句更为简单、直白,但是随着选项的越来越多,表驱动法就显得更易维护了。

分支代码如下:

func choose1(subtitle string) {
	switch subtitle {
	case "表驱动法":
		fmt.Println("分支一")
	case "提早返回":
		fmt.Println("分支二")
	case "状态模式":
		fmt.Println("分支三")
	case "空置判断":
		fmt.Println("分支四")
	}
}

表驱动法代码如下:

var subtitleMap  = map[string]string{
	"表驱动法":"分支一",
	"提早返回":"分支二",
	"状态模式":"分支三",
	"空置判断":"分支四",
}

func choose2(subtitle string){
	if val,ok := subtitleMap[subtitle];ok {
		fmt.Println(val)
	}
}

可以看到,choose方法很清晰整洁了,实际工作中mapval一般是对象或者func,此时其实就是工厂模式+策略模式的使用形式了。

三:快乐路径

快乐路径也即提早返回,一般用于参数校验或者错误处理等场景。

如下:

goodCase

//伪代码段1:

func doSomething() error {
  if errorCondition1 {
    // some error logic
    ... ...
    return err1
  }
  
  // some success logic
  ... ...

  if errorCondition2 {
    // some error logic
    ... ...
    return err2
  }

  // some success logic
  ... ...
  return nil
}


我们看到单分支控制结构的伪代码段 1 有这几个特点:

  • 没有使用 else 分支,失败就立即返回;
  • “成功”逻辑始终“居左”并延续到函数结尾,没有被嵌入到 if 的布尔表达式为 true 的代码分支中;
  • 整个代码段布局扁平,没有深度的缩进;
  • 代码的可读性很高

badCase

// 伪代码段2:

func doSomething() error {
  if successCondition1 {
    // some success logic
    ... ...

    if successCondition2 {
      // some success logic
      ... ...

      return nil
    } else {
      // some error logic
      ... ...
      return err2
    }
  } else {
    // some error logic
    ... ...
    return err1
  }
}

伪代码段 2 实现了同样逻辑码段 1,就使用了带有嵌套的二分支结构,它的特点如下:

  • 整个代码段呈现为“锯齿状”,有深度缩进;
  • “成功”逻辑被嵌入到 if 的布尔表达式为 true 的代码分支中;

很明显,伪代码段 1 的逻辑更容易理解,也更简洁。Go 社区把这种 if 语句的使用方式称为 if 语句的“快乐路径(Happy Path)”原则,所谓“快乐路径”也就是成功逻辑的代码执行路径,它的特点是这样的:

  • 仅使用单分支控制结构;

  • 当布尔表达式求值为 false 时,也就是出现错误时,在单分支中快速返回;

  • 正常逻辑在代码布局上始终“靠左”,这样读者可以从上到下一眼看到该函数正常逻辑的全貌;

  • 函数执行到最后一行代表一种成功状态。

Go 社区推荐 Gopher 们在使用 if 语句时尽量符合这些原则,如果你的函数实现代码不符合“快乐路径”原则,你可以按下面步骤进行重构:

  • 尝试将“正常逻辑”提取出来,放到“快乐路径”中;

  • 如果无法做到上一点,很可能是函数内的逻辑过于复杂,可以将深度缩进到else分支中的代码析出到一个函数中,再对原函数实施“快乐路径”原则。

四:状态模式

状态模式即之前一些博客介绍的,一般用于审批流,状态流转等场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值