有的时候,为了检查入参,会有很多项需要检查,如果一个一个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
}
1、易读性很差
2、修改麻烦
3、不易扩展
4、打印失败信息麻烦,需要每个异常分支添加
调整为如下方式:
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
}
1、条理清晰,易读性好
2、增加判断时,直接新增函数
3、打印失败信息也比较方便,且新增判断也不用新增打印
注:
对于函数名作为参数时,如果是传的方法,需要连对象一起传入。
如上的fn,传入时为c.checkXXX,c为这个方法的实际调用对象。
有疑问加站长微信联系(非本文作者)