前言
对于第三方接口进行交互的时候,往往需要大量的进行参数合法性校验。以前的方法就是对每个参数进行验证。如下截图:
上图的会存在大量的if else if else..,如果字段很多,那导致一个方法存在大量的验证的代码,那我们考虑是否可以进行统一的验证参数的合法性。
思路
平时建立类的时候我们可以写参数MAXLEN=100,TRUNCATE=1 是否截取等,那找找这些参数的定义地方。如截图:
那我们想要定义自己的参数,该如何定义呢?根据面向对象设计原则之一:
里氏替换原则(Liskov Substitution Principle,LSP):子类型必须能够替换掉他们的基类型。即,在任何父类可以出现的地方,都可以用子类的实例来赋值给父类型的引用。当一个子类的实例应该能够替换任何其超类的实例时,它们之间才具有是一个 (is-a) 关系
那我们可以自定义数据类型,继承%Library.String,这样子类继续使用父类的参数,还可以自定义自己的参数。此处以字符串为例,其他的数据类型一样的原理。
自定义类型就为String.
实现
- 自定义数据类型
`
/// 自定义数据类型实现继承的String
Class Design.DataType.String Extends %Library.String
{
/// 是否为空 1 必填 0 可以为空
Parameter NOTBLANK = 0;
/// 代码值,写取global的表达式? $XECUTE 执行?
Parameter DICCODE;
/// 不为空的错误消息
Parameter MESSAGE;
/// 错误码值错误
Parameter CODEERRMESSAGE;
/// 类型 INT,STRING,FLOAT,NUMBER,DATE,DATETIME
Parameter TYPE = "STRING";
/// 是否时间类型
Parameter ISDATE = 0;
/// 时间格式:yyyy-MM-dd=>3 yyyyMMdd=8 dd/MM/yyyy=1 默认
Parameter DATEFORMAT = 3;
/// 条件取值验证
Parameter CONDITION;
/// 是否需要在当前时间之后,比如预约时间
Parameter ISAFTER;
/// 是否在当前直接之前 比如出生日期
Parameter ISBEFORE;
}
`
2.定义模型类
`
Class Design.DataType.Person Extends (%RegisteredObject, %XML.Adaptor)
{
/// 姓名
Property pname As String(MAXLEN = 100, MESSAGE = "人员姓名不能为空!", NOTBLANK = 1, TRUNCATE = 1);
/// 生日
Property birth As String(DATEFORMAT = 3, ISBEFORE = 1, ISDATE = 1, MESSAGE = "出生日期不能为空!", NOTBLANK = 1, TRUNCATE = 1);
/// 性别
Property sexCode As String(CODEERRMESSAGE = "性别代码错误!", DICCODE = "$O(^CT(""SEX"",0,""Code"",", MAXLEN = 100, MESSAGE = "性别代码不能为空!", NOTBLANK = 1);
/// ...此处省略 民族,国籍,学历等等
/// 工作描述
Property job As Job;
}
`
3.统一验证的方法代码
`
/// 校验对象的工具类
Class Design.DataType.ValidUtil Extends %RegisteredObject
{
/// 判断对象是否有效
/// TODO:嵌套对象可以自己研究研究
ClassMethod IsValid(obj As %ObjectHandle, Output errmsg As %String) As %Status
{
s ClsName=obj.%ClassName(1)
s validFlag=$$$OK
s Name=""
f{
s Name=$o(^oddDEF(ClsName,"a",Name))
q:Name=""
s Val=$Property(obj,Name)
w Name_"="_Val,!
;获取属性对应的参数
;是否为空
s NOTBLANK=$g(^oddDEF(ClsName,"a",Name,"P","NOTBLANK"))
i (NOTBLANK=1)&&(Val=""){
s errmsg= $g(^oddDEF(ClsName,"a",Name,"P","MESSAGE"))
s validFlag=0
q
}
;是否码值校验
s DICCODE=$g(^oddDEF(ClsName,"a",Name,"P","DICCODE"))
i DICCODE'=""{
SET cmd="(out){ s out="_DICCODE_""""""_$$ALPHAUP^SSUTIL4(Val)_""",""""))"_" q 1}"
SET rtn=$XECUTE(cmd,.rowId)
i rowId="" {
s errmsg=$g(^oddDEF(ClsName,"a",Name,"P","CODEERRMESSAGE"))
s validFlag=0
q
}
}
;是否时间格式校验
s ISDATE=$g(^oddDEF(ClsName,"a",Name,"P","ISDATE"))
if ISDATE=1 {
s DATEFORMAT=$g(^oddDEF(ClsName,"a",Name,"P","DATEFORMAT"))
s result=$zdh(Val,DATEFORMAT,"","","","","","-1","时间格式错误","")
if result="时间格式错误"{
s errmsg="字段"_Name_"["_Val_"]"_"时间格式错误"
s validFlag=0
q
}
//时间与当前时间的验证
s ISBEFORE=$g(^oddDEF(ClsName,"a",Name,"P","ISBEFORE"))
if ISBEFORE=1{
if result>+$h {
s errmsg="字段"_Name_"["_Val_"]"_"不能超过当前日期!"
s validFlag=0
q
}
}
s ISAFTER=$g(^oddDEF(ClsName,"a",Name,"P","ISAFTER"))
if ISAFTER=1{
if result<+$h {
s errmsg="字段"_Name_"["_Val_"]"_"不能小于当前日期!"
s validFlag=0
q
}
}
}
}
q validFlag
}
}
`
测试
-
测试不为空
-
测试code错误
3.测试时间格式错误
4.测试时间的值先后
参数还需要进行大量的验证,此处只是示例,可能存在错误,欢迎批评纠正
提供了很好的思路