文章
· 九月 21, 2023 阅读大约需 4 分钟

通过自定义数据类型实现参数统一验证优化重构代码

前言

对于第三方接口进行交互的时候,往往需要大量的进行参数合法性校验。以前的方法就是对每个参数进行验证。如下截图:
image

上图的会存在大量的if else if else..,如果字段很多,那导致一个方法存在大量的验证的代码,那我们考虑是否可以进行统一的验证参数的合法性。

思路

平时建立类的时候我们可以写参数MAXLEN=100,TRUNCATE=1 是否截取等,那找找这些参数的定义地方。如截图:

image
那我们想要定义自己的参数,该如何定义呢?根据面向对象设计原则之一:

里氏替换原则(Liskov Substitution Principle,LSP):子类型必须能够替换掉他们的基类型。即,在任何父类可以出现的地方,都可以用子类的实例来赋值给父类型的引用。当一个子类的实例应该能够替换任何其超类的实例时,它们之间才具有是一个 (is-a) 关系

那我们可以自定义数据类型,继承%Library.String,这样子类继续使用父类的参数,还可以自定义自己的参数。此处以字符串为例,其他的数据类型一样的原理。
自定义类型就为String.

实现

  1. 自定义数据类型

`

/// 自定义数据类型实现继承的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
}

}

`

测试

  1. 测试不为空
    image

  2. 测试code错误
    image

3.测试时间格式错误
image

4.测试时间的值先后
image

1

参数还需要进行大量的验证,此处只是示例,可能存在错误,欢迎批评纠正

讨论 (1)3
登录或注册以继续