一、传统 IF 判断
1、在业务中使用大量的 if 判断
代码如下:
package main type SellInfo struct { Price float64 OrderCount int TotalCount int MemberShip int } func main2() { var a = SellInfo{ Price: 1.0, OrderCount: 1, TotalCount: 20, MemberShip: 1, } if a.Price > 0 { println("true") } if a.TotalCount > a.OrderCount { println("true") } if a.MemberShip == 1 { println("true") } if a.Price < 100 && a.MemberShip == 2 { println("true") } }
2、如果再继续添加新的条件?
在上面的代码中,如果业务又需要增加新的判断,继续添加if条件?这可能是无限if下去的无底洞?
if判断对cpu还是很消耗资源的(搜索:cpu对if分支判断),引入今天的主角:责任链。
责任链的思路:将一个复杂逻辑的流程进行分解,将每个判断条件的判断交给责任链节点进行处理,在处理完成后将结果传递给下一个节点。
二、责任链 KILL IF
1、正确使用接口与对象
代码如下:
package main import "fmt" type SomeConditions struct { Price float64 OrderCount int TotalCount int MemberShip int } type Rule interface { Check(s *SomeConditions) bool } type PriceCheck struct{} func (p *PriceCheck) Check(s *SomeConditions) bool { return s.Price > 0 }
这里定义了一个Rule的接口类型
接口: 在Go语言中接口(interface)是一种类型,一种抽象的类型
上面代码可以看到,有一个比较有意思的地方,就是使用了空结构体
type PriceCheck struct{}
然后在这个结构体上再追加一个实现接口的方法
func (p *PriceCheck) Check(s *SomeConditions) bool { }
2、go责任链核心代码
注意:这里需要判断业务的整体性,如果都是false,要求为true抛出返回,则需要更改如下代码
判断的整体业务是以true为基本,一旦发生false则抛出返回的原则
如下代码:
// 聚合所有条件 func chain(s *SomeConditions, rules ...Rule) bool { for _, rule := range rules { if !rule.Check(s) { return false } } return true }
3、go责任链完整代码
以下实现了设计原则:
package main import "fmt" type SomeConditions struct { Price float64 OrderCount int TotalCount int MemberShip int } type Rule interface { Check(s *SomeConditions) bool } // 聚合所有条件 func chain(s *SomeConditions, rules ...Rule) bool { for _, rule := range rules { if !rule.Check(s) { return false } } return true } func main() { SomeConditions := &SomeConditions{ Price: 1.00, OrderCount: 2, TotalCount: 10, MemberShip: 2, } rules := []Rule{ &PriceCheck{}, &OrderCountCheck{}, &MemberShipCheck{}, &DiscountCheck{}, } flag := chain(SomeConditions, rules...) fmt.Println(flag) } type PriceCheck struct{} func (p *PriceCheck) Check(s *SomeConditions) bool { return s.Price > 0 } type OrderCountCheck struct{} func (o *OrderCountCheck) Check(s *SomeConditions) bool { return s.TotalCount > s.OrderCount } type MemberShipCheck struct{} func (m *MemberShipCheck) Check(s *SomeConditions) bool { return s.MemberShip == 2 } type DiscountCheck struct{} func (d *DiscountCheck) Check(s *SomeConditions) bool { return s.Price > 10 && s.MemberShip == 2 }
标签:SomeConditions,Price,ELSE,Golang,代替,func,bool,type,Check From: https://www.cnblogs.com/beatle-go/p/17974695