有的时候,为了检查入参,会有不少项须要检查,若是一个一个if-else的去判断,会显得很low,先看一个比较丑的写法:函数
func checkQeuryParam(c *condition) bool { if c.offset > 100000 { return false } if c.limit > 100 { return false } if c.timebegin != "" { zone := time.FixedZone("CST", 8*3600) t, err := time.ParseInLocation("2006-01-02T15:04:05.000+0800", c.timebegin, zone) if err != nil { aialog.Error.Printf("Query time %s is invalid.\n", c.timebegin) return false } c.timebegin = t.Format("2006-01-02T15:04:05.000+0800") } //ip no check //come_from no check //event if c.event != "" { if c.event != "added" && c.event != "modified" && c.event != "deleted" { return false } } //ruleid if c.ruleid != "" { id, err := strconv.Atoi(c.ruleid) if err != nil { return false } //id range, temporary if id < 0 || id > 1000000 { return false } } if c.rulelevel != "" { level, err := strconv.Atoi(c.rulelevel) if err != nil { return false } //level range 0-16 if level < 0 || level > 15 { return false } } if c.agentid != "" { if len(c.agentid) > 64 { return false } } //order if c.order != "" { if c.order != "desc" && c.order != "asc" { return false } } return true }
一、易读性不好
二、修改麻烦
三、不易扩展
四、打印失败信息麻烦,须要每一个异常分支添加code
调整为以下方式:orm
func (c *condition)checkOffset() bool { if c.offset > 100000 { return false } return true } func (c *condition)checkLimit() bool { if c.limit > 100 { return false } return true } func (c *condition)checkTime() bool { if c.timebegin != "" { zone := time.FixedZone("CST", 8*3600) t, err := time.ParseInLocation("2006-01-02T15:04:05.000+0800", c.timebegin, zone) if err != nil { aialog.Error.Printf("Query time %s is invalid.\n", c.timebegin) return false } c.timebegin = t.Format("2006-01-02T15:04:05.000+0800") } return true } func (c *condition)checkEvent() bool { if c.event != "" { if c.event != "added" && c.event != "modified" && c.event != "deleted" { return false } } return true } func (c *condition)checkRuleid() bool { if c.ruleid != "" { id, err := strconv.Atoi(c.ruleid) if err != nil { return false } //id range, temporary if id < 0 || id > 1000000 { return false } } return true } func (c *condition)checkRulelevel() bool { if c.rulelevel != "" { level, err := strconv.Atoi(c.rulelevel) if err != nil { return false } //level range 0-16 if level < 0 || level > 15 { return false } } return true } func (c *condition)checkAgentid() bool { if c.agentid != "" { if len(c.agentid) > 64 { return false } } return true } func (c *condition)checkOrder() bool { if c.order != "" { if c.order != "desc" && c.order != "asc" { return false } } return true } func checkQeuryParam(c *condition) bool { checks := []struct{ name string fn func() bool }{ {"check offset", c.checkOffset}, {"check limit", c.checkLimit}, {"check time", c.checkTime}, {"check event", c.checkEvent}, {"check rule id", c.checkRuleid}, {"check rule level", c.checkRulelevel}, {"check agent id", c.checkAgentid}, {"check order", c.checkOrder}, } for _, check := range checks { if !check.fn() { aialog.Error.Printf("%s failed.\n", check.name) return false } } return true }
一、条理清晰,易读性好
二、增长判断时,直接新增函数
三、打印失败信息也比较方便,且新增判断也不用新增打印对象
注:
对于函数名做为参数时,若是是传的方法,须要连对象一块儿传入。
如上的fn,传入时为c.checkXXX,c为这个方法的实际调用对象。ip