亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

實現一個對象驗證庫系列--1)接口介紹以及總體思路概述(請大神批評)

2019-11-14 13:53:42
字體:
來源:轉載
供稿:網友

前情回顧:

上一篇 0) 目錄以及庫結構介紹 簡單描述了下庫的代碼結構

本文將從接口部分闡述總體的思路

1) 接口介紹以及總體思路概述

如下圖,我總共定義了10個Interface

這些實際可分為兩類:

  • 為了支持 Fluent 語法格式而定義的各個創建者接口
    • IFluentRuleBuilder
    • IRuleBuilder
    • IRuleMessageBuilder
    • IValidateRuleBuilder
    • IValidatorBuilder
    • IValidatorSetter
  • 驗證操作涉及的規則、結果、驗證調用接口的定義:
    • IRuleSelector
    • IValidateResult
    • IValidateRule
    • IValidator

 

接下來我們首先闡述下驗證使用方式的接口設計思路,

然后再介紹 Fluent 格式的規則設置方式的設計思路。

(1)驗證使用方式的接口設計思路

我們首先考慮的用戶的驗證使用方式,而且我們是提供用戶自行設置驗證規則,不是只是提供一些固定的驗證規則,

那么用戶其實只是想給一個數據,然后拿到對應的結果就行

所以大致接口設想就是

public interface IValidator{	object Validate(object data);}

方法是這樣,用戶拿到返回值怎么方便使用呢?

思考一番,思路都是類似如下的

public interface IValidateResult{	bool IsValid { get; }  // 使用者肯定首先在乎驗證時候通過	List<ValidateFailure> Failures { get; }  // 如果不通過,會有什么錯誤信息}// 錯誤信息的類,使用者一般都是關注那個地方出錯,出了什么錯,原始的值是什么才導致了錯誤public class ValidateFailure{	public string Name { get; set; }	public object Value { get; set; }	public string Error { get; set; }}
// 所以接口可以改成這樣public interface IValidator{ IValidateResult Validate(object data);}

思考一下參數,object肯定不是滿足的:

public class ValidateContext{	public IRuleSelector RuleSelector { get; set; }		// 很多時候,用戶可能只是使用其中一些驗證規則,比如驗證學生信息時,大學生和幼兒園同學肯定是不一樣的														// 所以用戶得有一個實現如何選擇驗證規則方式的規則選擇器	public IEnumerable<string> RuleSetList { get; set; }  // 大部分時候,規則選擇器都是一樣,但是規則選擇只需用戶設置一些標志,一個默認實現的規則選擇器基本夠用了	public ValidateOption Option { get; set; }  		// 有時候用戶可能需要全部錯誤,但是有時會先check null,不為null才做其他驗證	public object ValidateObject { get; set; }}public enum ValidateOption{	StopOnFirstFailure,	Continue}public interface IRuleSelector{	bool CanExecute(IValidateRule rule, ValidateContext context);}// 所以最終接口這樣就可以了public interface IValidator{	IValidateResult Validate(ValidateContext context);}

接口方法這樣可以了,但是驗證規則如何保存呢?思考如下:

public interface IValidateRule{	string RuleSet { get; set; } // 規則分組的標志,大多數情況就可以滿足用戶對一個對象不同情境的驗證分組	IValidateRule NextRule { get; set; }  // 一個規則與其他規則常有關聯性,比如先check 為null,然后再check 長度,都放在一個class中肯定不方便我們定義與使用	string ValueName { get; set; }	// 有check 數據的名字屬性,這樣用戶可以改變這個名字	string Error { get; set; } // 有展示錯誤的屬性,這樣用戶可以改變這個屬性值	Func<ValidateContext, bool> Condition { get; set; }  // 規則分組如果不滿足用戶,就只能提供這樣的func讓用戶自行篩選了	Func<ValidateContext, string, string, IValidateResult> ValidateFunc { get; set; } // 之所以有這個屬性,是為了便利地拓展check的logic,不必每個新的規則check方式都必須寫一個ValidateRule類	IValidateResult Validate(ValidateContext context);  // 提供規則調用的接口}

(2)Fluent 格式的規則設置方式的設計思路

上面我們以及思考到了如何保存驗證規則,那么我們如何用 Fluent 的方式設置規則呢?

首先我們拋開 Fluent 的理念,想一下我們如何創建規則呢?

是不是這樣呢?

new ValidateRule() {	RuleSet = "xx",	ValueName = "xx"	.....}

回憶一下 Fluent 的方式,鏈式的語法,而且在我們這里用來設置驗證規則,簡直就是創建者模式的鏈式使用而已

ValidateRule.SetRuleSet("xx").SetValueName("xx")

 所以如下我們有了規則的創建者

public interface IValidateRuleBuilder{  string RuleSet { get; set; }  string ValueName { get; set; }  string Error { get; set; }  Func<ValidateContext, bool> Condition { get; set; }  IValidateRuleBuilder NextRuleBuilder { get; set; }  Func<ValidateContext, string, string, IValidateResult> ValidateFunc { get; set; }  IValidateRule Build(); // 大致與IValidateRule差不多,只是多了這個Build 方法}public interface IValidatorBuilder<T>{  IFluentRuleBuilder<T, TPRoperty> RuleFor<TProperty>(Expression<Func<T, TProperty>> expression);  void RuleSet(string ruleSet, Action<IValidatorBuilder<T>> action);  IValidator Build();}

  

Fluent 設計時都是大致設想最終效果類似什么樣,才能建立對應的接口這些定義

我們回想一下我們的最終效果是什么樣呢?

ValidatorBuilder.RuleFor(i => i.Age)        .Must(i => i >= 0 && i <= 18)        .OverrideName("student age")        .OverrideError("not student")    .ThenRuleFor(i => i.Name)        .Must(i => !string.IsNullOrWhiteSpace(i))        .OverrideName("student name")        .OverrideError("no name");

解釋一下我們最終的效果:

ValidatorBuilder.RuleFor(i => i.Age)  //一個 ValidatorBuilder 才能創建父級驗證規則,并會設置對應驗證的屬性        .Must(i => i >= 0 && i <= 18)  // 每個規則必須設置如何驗證方法		        .OverrideName("student age")        .OverrideError("not student")  // 設置一些需要復寫的信息		    .ThenRuleFor(i => i.Name)         // 只有設置完了一個規則的驗證方法之后才能建立子級規則        .Must(i => !string.IsNullOrWhiteSpace(i))        .OverrideName("student name")        .OverrideError("no name");

總體來說我們將一個規則的設置分成了幾個階段,并且這些階段是不可逆的,有著嚴格順序的

  • 初始創建父級驗證規則,并會設置對應驗證的屬性
  • 設置如何驗證方法
  • 填寫一些描述信息或者建立子級規則

如此我們的接口便會是如下:

public interface IValidatorBuilder<T>{	IFluentRuleBuilder<T, TProperty> RuleFor<TProperty>(Expression<Func<T, TProperty>> expression);	void RuleSet(string ruleSet, Action<IValidatorBuilder<T>> action);	IValidator Build();}// 對應 初始創建父級驗證規則,并會設置對應驗證的屬性 這個階段public interface IFluentRuleBuilder<T, TProperty>{}// 對應 設置如何驗證方法 這個階段public interface IRuleMessageBuilder<T, TValue>{	IFluentRuleBuilder<T, TProperty> ThenRuleFor<TProperty>(Expression<Func<T, TProperty>> expression);}// 對應 填寫一些描述信息或者建立子級規則 這個階段public interface IRuleBuilder<T, TValue> : IValidateRuleBuilder, IRuleMessageBuilder<T, TValue>, IFluentRuleBuilder<T, TValue>{	Func<object, TValue> ValueGetter { get; }	Expression<Func<T, TValue>> ValueExpression { get; }	void SetValueGetter(Expression<Func<T, TValue>> expression);}// 總結三個階段的最終定義

以上全部就是接口的設計思路

后面將慢慢的描述如何實現

 

 

NEXT: 2) 驗證器實現


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美视频在线观看免费| 欧美在线一级va免费观看| 欧美黑人性生活视频| 国产91色在线|免| 欧美高清视频免费观看| 国产噜噜噜噜噜久久久久久久久| 狠狠色狠狠色综合日日小说| 亚洲性日韩精品一区二区| 成人国产精品一区二区| 亚洲欧美中文日韩在线v日本| 狠狠色香婷婷久久亚洲精品| 日产精品99久久久久久| 日韩免费在线视频| 久久久999精品视频| 在线精品国产欧美| 欧美专区在线播放| 日韩在线www| 日韩av免费观影| 97精品久久久中文字幕免费| 亚洲天堂av女优| 国产啪精品视频| 91久久久久久国产精品| 国产成人精品视频在线| 亚洲欧美精品伊人久久| 日韩高清免费观看| 日韩av电影中文字幕| 欧美精品中文字幕一区| 18性欧美xxxⅹ性满足| 国产精品入口免费视频一| 狠狠躁18三区二区一区| 96sao精品视频在线观看| 亚洲国产精品视频在线观看| 国产精品久久久久久一区二区| 国产亚洲精品久久久久久牛牛| 久久久999成人| 91精品中国老女人| 久久精品视频网站| 日韩欧中文字幕| 97在线观看视频| 国色天香2019中文字幕在线观看| 国产99久久精品一区二区 夜夜躁日日躁| 91精品在线观看视频| 久久中文字幕在线视频| 亚洲欧洲高清在线| 欧美成年人视频| 亚洲裸体xxxx| 国产精品视频精品视频| 97久久精品人人澡人人爽缅北| 亚洲电影免费观看高清完整版在线观看| 91在线国产电影| 国产一区深夜福利| 成人xvideos免费视频| 精品亚洲一区二区三区四区五区| 国产精品免费在线免费| 日韩精品在线电影| 午夜精品福利电影| 亚洲人成在线观看网站高清| 中文字幕国产精品| 国产福利成人在线| www.亚洲人.com| 亚洲精品成人久久久| 亚洲视频国产视频| 亚洲精品第一国产综合精品| 欧美成人性生活| 精品视频久久久| 日韩网站免费观看| 免费av一区二区| 久久亚洲欧美日韩精品专区| 欧美日韩国产综合视频在线观看中文| 中文字幕精品国产| 亚洲自拍在线观看| 日韩av三级在线观看| 日韩中文字幕免费视频| 亚洲片国产一区一级在线观看| 久久免费国产精品1| 福利视频一区二区| 91免费在线视频网站| 久久久之久亚州精品露出| 欧美大片在线看免费观看| 欧美电影在线观看完整版| 国产精品极品美女粉嫩高清在线| 久久影院中文字幕| 国产精自产拍久久久久久| 欧美激情一区二区三区成人| 日韩三级影视基地| 亚洲免费电影在线观看| 国产精品综合不卡av| 欧美性猛交xxxx黑人猛交| 美日韩丰满少妇在线观看| 中文字幕在线看视频国产欧美| 亚洲影视九九影院在线观看| 日韩av成人在线观看| 欧美综合一区第一页| 欧美性猛交xxxx乱大交3| 国产99久久精品一区二区| 好吊成人免视频| 亚洲欧美色图片| 日韩av不卡在线| 亚洲一区二区中文字幕| 欧美色视频日本高清在线观看| 爱福利视频一区| 亚洲精品国产精品久久清纯直播| 欧美在线视频a| 国产成人精品国内自产拍免费看| 久久九九免费视频| 一区国产精品视频| 亚洲精品日韩激情在线电影| 亚洲一区二区三区在线视频| 在线观看日韩欧美| 欧洲永久精品大片ww免费漫画| 欧美激情精品久久久| 97视频在线观看视频免费视频| 韩国一区二区电影| 色综合视频一区中文字幕| 欧美精品18videos性欧| 亚洲色图av在线| 高清欧美性猛交xxxx| 国产精品久久久久久久久久99| 日韩黄色在线免费观看| 日本最新高清不卡中文字幕| 亚洲电影免费观看高清| 美女黄色丝袜一区| 欧美丝袜第一区| 少妇久久久久久| 国产精品欧美久久久| 国产精品91一区| 91精品国产综合久久男男| 亚洲精品不卡在线| 亚洲国产成人在线播放| 九九热99久久久国产盗摄| 人人爽久久涩噜噜噜网站| 亚洲精品久久在线| 亚洲人成电影网站色xx| 久久久精品美女| 亚洲天堂成人在线视频| 国产日韩精品一区二区| 中文字幕最新精品| 精品伊人久久97| 国产视频欧美视频| 日韩在线视频观看正片免费网站| 日韩欧美亚洲范冰冰与中字| 亚洲欧美综合另类中字| 国产一区二区在线免费视频| 国产精品96久久久久久| 久久国产精品久久久久久久久久| 国产成人久久精品| 欧美激情视频网址| 91在线精品视频| 久久久噜久噜久久综合| 国产精品电影观看| 久久天堂电影网| 亚洲精品一区二区网址| 亚洲无亚洲人成网站77777| 国产精品va在线播放我和闺蜜| 日韩免费中文字幕| 黄色成人av网| 国产精品jvid在线观看蜜臀| 人体精品一二三区| 亚洲综合色激情五月| 国产欧美日韩最新| 国产91色在线|| 久久久久久中文字幕| 久久av.com| 久久精品电影一区二区|