zoukankan      html  css  js  c++  java
  • CommonLibrary之Validation

      CommnLibrary是我目前看到的写的最好的开源通用类库,七七八八包含了如 40个左右的通用模块,代码写的也非常的棒,现在找点时间来详细的学习,记录一些常用模块,以便替换以前的通用类库.

      Validation

      当我看到这个验证的模块的实现应用方式让我眼睛一亮,

     

    Validation.IsNumeric("asdklf")
    //参数1:文本值  参数2:能否为空
    Validation.IsAlphaNumeric("asd123dsd43", false)
    
    //参数1:文本值  参数2:能否为空,3,4,是否检验最大(小)长度,5,6最大(小)长度
    Validation.IsStringLengthMatch("user01", false, true, true, 2, 12)
    
    //使用一个errors对象保存错误集合
    var errors = new Errors();
    Validation.IsAlpha("123abc", false, errors, "");
    
    //使用lamda表达式进行验证
    var val = new Validator(valEvent =>
                {
                    int errCount = valEvent.Results.Count;
                    Validation.IsEmail("kishore@", false, valEvent.Results, string.Empty);
                    Validation.IsUrl("http://www", false, valEvent.Results, string.Empty);
                    Validation.IsPhoneUS("111-111-111", false, valEvent.Results, string.Empty);
    
                    return errCount == valEvent.Results.Count;
                });
                PrintErrors(val.Validate());
    
    // 4.使所有的类型验证在一个对象中搞定
                var val = new ValidatorWithRules();
                val.Add(e => Validation.IsEmail("kishore@", false, e.Results, string.Empty));
                val.Add(e => Validation.IsUrl("http://www", false, e.Results, string.Empty));
                val.Add(e => Validation.IsPhoneUS("111-111-111", false, e.Results, string.Empty));
                PrintErrors(val.Validate());
    
    //5.使用链式调用进行验证
    val.Check(() => user.UserName).IsNotNull().IsBetween(1, 50)
                   .Check(() => user.CreateDate).IsAfterToday()
                   .Check("邮箱", user.Email).IsValidEmail()
                   .Check(() => user.MobilePhone).IsValidPhoneUS();
    //6.一次执行多个自定义类的验证 结果保存在一个集合之中
    var validators = new List<IValidator>()
                {
                    new MyCustomUserIdValidator("admin"),
                    new MyCustomUserIdValidator("batman")
                };
    
                // Run all the validators and collect the errors.
                ValidationResults errors = new ValidationResults();
                ValidationUtils.Validate(validators, errors);
    

     看了上面几个方法,服务端的所需的验证都包含在了里面,接下来,从整体的设计到每种方法的实现来分析一下这个模块的实现:

    Validation模块接口关系图:

       最初看到这个,觉得这个功能模块设计的比较复杂,但是弄清楚了具体的关系,其实还是比较复杂。最开始从IErrors,Errors,IValidationResults,ValidationResults开始看.

      IErrors接口定义了操作集合的一些方法和属性,Errors类实现该接口,通过一个Dictionary<string,string>,List<string>来保存错误信息,这里用了2个集合保持错误信息,Dictionary加上的原因是为了key对应验证的错误说明,Value对应错误值,比如说:key:用户名 value:不能为空


      IValidationResults接口继承Ierrors接口,只有一个属性,bool IsValide,来控制验证是否通过,而ValidationResults继承了该接口和IErrors接口,里面只定义了一个readonly的自己对象本身,这样定义好处是不仅能使用得到Errors类的公有方法,而且加上了自己对错误集合(Errors类中的2个集合的)控制,使得错误集合不能被更改,这样的设计能最大限度的加大代码的灵活性和分工的明确性,但是我觉得太过繁琐,要是我设计的话会去掉IValidationResults接口和ValidationResults  类,在IError和Errors类中做控制:)


      IValidatorStatefulIValidatorNoneStateful接口定义了验证方法,不同在于,NoneStateful不保存对象状态,这样做允许所有验证在一个方法中搞定


      IValidator接口继承了IValidatorStatefulIValidatorNoneStateful接口,这里它只是一个空接口


      IValidatorWithRules继承IValidator接口,这个接口用于定义自定义验证


       Validator类,继承了IValidator这个接口,实现了IValidatorStateful,IValidatorNoneStateful的所有方法


      ValidatorWithRules继承Validator类,实现IValidatorWithRules接口


      IValidator为空接口,这里这样做多态的灵活性出来了,Validator类中,几个实现方法被定义成了虚方法,便于继承者重写整个接口的关系,我感觉设计的太过复杂,也是项目性质不一样,内部的复杂设计,带来的高度的灵活性和扩展性,封装成一个DLL,调用的人只要知道如何调用就行,通用类库维护人员来控制代码的扩展和维护,在平时做这样的设计,对程序对代码的理解水平要求有一点,在项目里面还不能大面积讨论,不然讨论个10天半个月最后定下来一个类就搞定,呵呵,扯远了。

    这篇水文写到这已经3天时间了,犀利啊。每天晚上抽点时间写一点,为平淡的生活找点乐子吧。现在讨论具体的实现。今天看了景春雷同志写的在自己的项目中实现 Fluent Interface(流畅接口),春雷哥哥理解的蛮好的,学习。今天先写写在CommnLibrary中ValidatorFluent的实现吧,

    ValidatorFluent

       调用代码在最上面的用例5中,如Jquery的链式调用的语法写着很舒服,这样的语法格式能让代码简单,"高效",思维连贯。实现并不复杂,看看该类中的代码,所有方法返回this,便于链式调用的继续,让我感到吃惊的是作者在该类中加上了一个:

     public ValidatorFluent End()
            {
                return this;
            }
    

    用人的思考方式来书写供计算机阅读的代码,大大增加了代码的可读性,而我理解的扩展方法的作用一部分意义也在于此。除此之外,首先Check方法有3个重载,Check(Expression<Func<object>> exp)支持了表达式的解析,另外2个Check方法为什么不用泛型T来传参数?在这个类中,传递泛型意义不大,某些验证中所有类型还是要进行类型推断或者转换成特定类型(如:string); 在这个类中,结合了Validation类的验证,如果需要,还可以继续增加上IsDate,IsNumeric的Validation类的验证。所有的验证错误信息,全部放在前面说的ValidationResults类的集合中,进行合并处理。

    太晚了,先睡了,明天在继续写,想什么都讲,结果发现很多地方只要看一眼就明白,不需要讲,也不知道此类文章该怎么写才能分享我的一些浅薄的认识,希望大家能提供点这方面意见。

  • 相关阅读:
    物理课件开发记录之一2013年10月25日
    以as中的泛型数组举一例看帮助手册优化的好处
    flash的显示列表的机制探索一
    组合模式
    actionscript中重写注意事项
    用adobe air写一个金鱼监控程序
    adobe air桌面应用程序在前端显示,类似于暴风的总是在桌面的最上方
    windows7下的cmd命令之powercfg命令,不常用的
    设置默认访问项目的客户端的浏览器版本(IE版本)
    防火墙设置对外开放端口
  • 原文地址:https://www.cnblogs.com/mmmjiang13/p/1806877.html
Copyright © 2011-2022 走看看