有的時候,爲了檢查入參,會有不少項須要檢查,若是一個一個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