
我们先对手机号码进行分析:
特性:
1、11位数字,11位分为三段,前3位是网络识别号,4-7位是地区编码,8-11位才是用户的号码
2、1[3-9]开头
3、默认国家区号:86
这还只是中国的手机号码的属性,每个国家有对应的属性规则,可以看出手机号码也是一个具有复杂结构的对象。
开发中我们需要对手机号码进行多种操作,比如验证手机号码格式是否正确,17开头的虚拟号码禁止注册等等:
方法:
1、手机号码格式是否正确
2、是否虚拟号码
至此回答了上篇文章留下的问题,手机号码的检验逻辑应该放在手机号码的对象里。
type Mobile struct {
Value string `binding:"number,mobile"`
}
func (o Mobile) Validate() error {
if !regexp.MustCompile(`^(1[3-9][0-9]\d{8})$`).MatchString(o.Value) {
return errors.New("手机号码格式不正确")
}
return nil
}
func (o Mobile) IsVirtual() bool {
return strings.HasPrefix(o.Value, "17")
}
以上代码借鉴了Google Protobuf3中的Wrapper类型结构,以Value字段作为对象的值属性,针对Value字段做不同的业务操作。
那么又该如何使用这种类型的对象呢?
type UserLogin struct {
Mobile vo.Mobile
Captcha vo.Captcha
}
我们在request层的结构体直接使用Mobile对象,由于Mobile字段是对象,所以传参如下:
http://127.0.0.1:8080/user/login?Mobile={"Value":"13000000000"}&Captcha={"Value":"1234"}
{
"Code": 200,
"Message": "OK",
"Success": true,
"Data": {
"Mobile": {
"Value": "13000000000"
},
"Captcha": {
"Value": "1234"
}
}
}
我们把公共的属性放在domain层的vo目录中,用户的Age、Level、Nickname放在domain层的user目录,原因同上文。
http://127.0.0.1:8080/user/login?Mobile=13000000000&Captcha=1234
http://127.0.0.1:8080/user/login?Mobile={"Value":"13000000000"}&Captcha={"Value":"1234"}
由于参数使用了对象,原本简单的传参,现在参数格式必须为json对象,接口对接的开发者肯定满腹怨言,有没有更好的解决方式呢,请看下文分解。