返回

告别繁复 if 条件语句,一招学会规则执行器替代方案

闲谈

最近在公司领到一个小需求,需要对之前已有的试用用户申请规则进行拓展。按照上述的条件我们可以得出的结论是:

  • 咱们的主要流程主要是基于 and 或者 or 的关系。

  • 基于现有的一些产品限制,我们不能使用 es 这种动态语言,也无法直接在数据库中存储复杂的 json,只能基于已有字段判断。

    基于如上两个问题,我们其实可以想到,这个规则的本质就是一个树形结构,即树根为 and 或者 or,树枝是各个维度,树叶就是对应维度的值。

有了这个思路,我们就很好办了,首先给我们的规则执行器设计好接口,参数就是我们自定义的规则 json,返回值是是否满足规则。

type Validator interface {
	Validate(rules interface{}) (bool, error)
}

我们定义了一个接口,用来强制要求实现这个接口的对象需要实现 Validate 函数,这个函数的参数和返回值都已经声明好了,所以我们实现这个接口的对象只需要实现 Validate 函数的具体逻辑即可。

接着我们就可以写一个默认的规则执行器了。

type DefaultValidator struct {
}

func (v *DefaultValidator) Validate(rules interface{}) (bool, error) {
	ruleMap, ok := rules.(map[string]interface{})
	if !ok {
		return false, errors.New("rules must be a map[string]interface{}")
	}

	return v.validateMap(ruleMap), nil
}

func (v *DefaultValidator) validateMap(ruleMap map[string]interface{}) bool {
	for k, v := range ruleMap {
		switch k {
		case "and":
			return v.validateAnd(v.([]interface{}))
		case "or":
			return v.validateOr(v.([]interface{}))
		default:
			return false
		}
	}

	return false
}

func (v *DefaultValidator) validateAnd(rules []interface{}) bool {
	for _, rule := range rules {
		ruleMap, ok := rule.(map[string]interface{})
		if !ok {
			return false
		}

		if !v.validateMap(ruleMap) {
			return false
		}
	}

	return true
}

func (v *DefaultValidator) validateOr(rules []interface{}) bool {
	for _, rule := range rules {
		ruleMap, ok := rule.(map[string]interface{})
		if !ok {
			return false
		}

		if v.validateMap(ruleMap) {
			return true
		}
	}

	return false
}

这个规则执行器很简单,它只实现了两种最基本的规则:and 和 or。接下来我们就可以使用这个规则执行器来处理我们的规则了。

func main() {
	validator := DefaultValidator{}

	rules := map[string]interface{}{
		"and": []interface{}{
			map[string]interface{}{
				"field1": "value1",
			},
			map[string]interface{}{
				"field2": "value2",
			},
		},
	}

	result, err := validator.Validate(rules)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(result)
}

运行这个程序,我们将会得到以下输出:

true

这表明我们的规则执行器能够正确地处理我们的规则。

规则执行器是一种强大的工具,它可以帮助我们更轻松地处理复杂的条件判断。在本文中,我们介绍了如何使用规则执行器来替代传统的 if-else 语句。我们还提供了一个简单的规则执行器实现,供您参考。希望本文对您有所帮助。