Golang Go语言中链式写法是否易于CR或维护呢?纠结中

发布于 1周前 作者 yibo5220 来自 Go语言

这里对需求进行了简化,实际上真实的业务需求每个Condition包含非常复杂的逻辑,如果全都用 if 嵌套来实现,只能拆分成一个一个的方法

后来想到能否直接表示出整个链条,就改写成了下面的样子,求各位大佬帮忙看下这种写法的优缺点, 如果有更好的方法, 也请大佬们指点一二

package main

import ( “log” )

type ConditionUnitItf interface { Condition(interface{}) (bool, error) }

type ConditionUnitWrapper struct { Params interface{} Result interface{} ConditionUnit ConditionUnitItf TrueHandler *ConditionUnitWrapper FalseHandler *ConditionUnitWrapper }

// NewUnit … func NewUnit(unit ConditionUnitItf) *ConditionUnitWrapper { return &ConditionUnitWrapper{ ConditionUnit: unit, } }

// True 设置这个实例的下一个 handler func (s *ConditionUnitWrapper) True(nextHandler *ConditionUnitWrapper) *ConditionUnitWrapper { s.TrueHandler = nextHandler.WithParams(s.Params) return s }

func (s *ConditionUnitWrapper) False(nextHandler *ConditionUnitWrapper) *ConditionUnitWrapper { s.FalseHandler = nextHandler return s }

// WithParams 给实例设置参数 func (s *ConditionUnitWrapper) WithParams(params interface{}) *ConditionUnitWrapper { s.Params = params return s }

func (s *ConditionUnitWrapper) SetResult(r interface{}) *ConditionUnitWrapper { s.Result = r return s }

// Run 构造 chain 的核心逻辑,除了叶子节点,其他的 Condition Unit 都使用了 Condition Base 的 Run 方法 func (s *ConditionUnitWrapper) Run() (*ConditionUnitWrapper, error) { isTrue, err := s.ConditionUnit.Condition(s.Params) if err != nil { return nil, err }

if isTrue && s.TrueHandler != nil {
	// 这里使用 WithParams 将参数传递给 handler
	return s.TrueHandler.WithParams(s.Params).Run()
}

if !isTrue && s.FalseHandler != nil {
	return s.FalseHandler.WithParams(s.Params).Run()
}

return s, nil

}

// ===================== 上面是实现了,下面要实现多个 条件单元 type userParams struct { IsInCompany bool // 工作时间是否小于 10 小时 Destination string // 目的地是 家 还是 餐厅 IsNeedWorkAtHome bool // 是否在家要工作 IsHungry bool // 是否饿了 LastAction int // 最后的结果行为 }

// 定义 3 个行为 const ( HumanActionWork = iota // 工作 HumanActionEating // 吃饭 HumanActionRest // 休息 )

// 下面我要构造条件链路,按照当前的 user 状态(userParams) 来计算下一步的行为

// 条件链路包含的单元为 // 1. 是否在公司 // 2. 是否回家了 // 3. 是否饿了 // 4. 是否继续工作

// 上面出现了 4 个条件判断,所以下面我要创建四个条件单元

// 是否下班 type UnitIsInCompany struct { }

// 实际的代码逻辑中,每一个 Condition 可能会包含更加复杂的逻辑 func (s UnitIsInCompany) Condition(params interface{}) (bool, error) { return params.(userParams).IsInCompany, nil }

// 是否回家 type UnitIsDestinationHome struct { }

func (s UnitIsDestinationHome) Condition(params interface{}) (bool, error) { return params.(userParams).Destination == “home”, nil }

// 是否饿了 type UnitIsHungry struct { }

func (s UnitIsHungry) Condition(params interface{}) (bool, error) { return params.(userParams).IsHungry, nil }

// 是否需要继续工作 type UnitIsNeedWorkAtHome struct { }

func (s UnitIsNeedWorkAtHome) Condition(params interface{}) (bool, error) {

if params.(userParams).IsNeedWorkAtHome {
	return true, nil
}
return false, nil

}

// ===================== 下面还要针对条件写叶子结点的结构

// 对于叶子节点而言, 主要是用于收尾,调用 SetResult type LeafUnitEchoAction struct { }

func (s LeafUnitEchoAction) Condition(params interface{}) (bool, error) { return true, nil }

func main() { user := userParams{ IsInCompany: false, Destination: “home”, IsNeedWorkAtHome: false, IsHungry: false, } // 按照条件构造的链路为如下: obj, err := NewUnit(UnitIsInCompany{}).WithParams(user). // 如果在公司,就工作 True(NewUnit(LeafUnitEchoAction{}).SetResult(HumanActionWork)). // 如果不在公司,判断目的地是否是 Home False( NewUnit(UnitIsDestinationHome{}). // 回家后是否需要继续工作 True( NewUnit(UnitIsNeedWorkAtHome{}). // 继续工作 True(NewUnit(LeafUnitEchoAction{}).SetResult(HumanActionWork)). // 不工作就休息 False(NewUnit(LeafUnitEchoAction{}).SetResult(HumanActionRest))). // 不回家,是否饿了 False(NewUnit(UnitIsHungry{}). // 饿了就去餐厅吃饭 True(NewUnit(LeafUnitEchoAction{}).SetResult(HumanActionEating)). // 不饿就休息 False(NewUnit(LeafUnitEchoAction{}).SetResult(HumanActionRest)))). Run()

if err != nil {
	log.Fatalf("err is %v", err)
}

// 最后通过 GetParams 获取到 LastAction
log.Printf("action is %v", obj.Result)

}


Golang Go语言中链式写法是否易于CR或维护呢?纠结中

更多关于Golang Go语言中链式写法是否易于CR或维护呢?纠结中的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

还有这种,是不是降低了圈复杂度。。。。

更多关于Golang Go语言中链式写法是否易于CR或维护呢?纠结中的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


看着有比较明显的范式:满足 condition 1 执行 action 1 。

做一下接口抽象,责任链来编排一下,具体的编排通过配置文件来实现,交给产品、业务自己去配置,不要 hardcode 翻译到代码里面。

作为IT领域Go语言方面的专家,对于Golang中链式写法的CR(Code Review,代码审查)和维护性问题,有以下见解:

链式写法在Go语言中通常涉及链式结构体,这种设计方法通过指针或引用来连接多个结构体,形成链表。其优势在于灵活性高、存储压缩效果好、操作简便,适用于数据结构、算法和操作系统等多个领域。

然而,在CR和维护性方面,链式写法可能带来一些挑战。首先,链式写法可能增加代码的复杂性,特别是在链表较长或涉及多层嵌套时,阅读和理解代码可能会变得困难。其次,链式写法中的节点操作(如插入、删除和修改)需要谨慎处理,以避免内存泄漏和指针错误等问题,这增加了维护的难度。

为了提高链式写法的CR和维护性,建议遵循以下最佳实践:

  • 确保链式结构体的设计简洁明了,避免不必要的复杂性。
  • 在CR过程中,仔细检查链式写法的逻辑正确性和内存安全性。
  • 对链式写法的代码进行充分测试,包括单元测试和集成测试,以确保其稳定性和可靠性。

总之,链式写法在Go语言中具有一定的优势,但在CR和维护性方面需要特别注意。通过遵循最佳实践,可以有效地降低其复杂性并提高代码质量。

回到顶部