我知道的JavaScript设计模式(桥接)应用之验证器

引子:

首先请各位同学跟我来一起复习设计模式中的桥接模式(Bridge), 废话不多言表直接上图:

 

在这个设计模式中我们的抽象类和实现类可以各自进行扩展和封装这样就可以对它们进行脱耦, 通过组合来产生很多变化。这种思想也符合“少用继承,多用组合”的设计原则.在桥接模式中我们可以用Abstraction 类来对实现类(ConreteImplementor)和修正抽象化类(RefinedAbstraction)进行桥接。但JavaScript 如何实现桥接呢?Please follow me 

 1 //Validation类:
2
3 view plain
4 Validation= {
5 required: function(elem) {
6 return!$(elem).val().trim().isNullOrEmpty();
7 },
8 email: function(elem) {
9 returnValidation.regexValidator($(elem).val().trim(),Validation.Regex.email);
10 },
11 regexValidator: function(elemVal, /*string*/regex,) {
12 if(!elemVal.isNullOrEmpty() && !(elemVal.match(regex, "\g"))) {
13 returnfalse;
14 } else{
15 returntrue;
16 };
17 },
18 Regex: {
19 email:/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)?$/
20 }
21 };
22 Validation.validateColl= {
23 'jq-validation-required': {validFunc:Validation.required, ErrMsg: 'Required'},
24 'jq-validation-email': {validFunc:Validation.email, ErrMsg: 'Invalid email address'}
25 };
26 Validator类:
27
28 view plain
29 (function () {
30 varvalidator_elements_blur_selector = 'input[type="text"]';
31 varvalidator_elements_change_selector = 'select,input[type="hidden"]';
32 var validator_elements_selector =validator_elements_blur_selector + ',' +validator_elements_change_selector;
33
34 Validator = function(validateScopeSelector) {
35 this._validateColl= $.extend(true, {}, Validation._validateColl);
36 this._validateDom= $(validateScopeSelector);
37 vartheValidator = this;
38 this._validateDom.delegate(validator_elements_blur_selector,'blur',function() {
39 theValidator.validateInput(this, 'blur');
40 });
41 this._validateDom.delegate(validator_elements_change_selector,'change', function() {
42 varinputValidated = theValidator.validateInput(this,'change');
43 });
44 };
45
46 Validator.prototype = {
47 validate: function() {
48 varvalidated = true;
49 vartheValidator = this;
50 $(validator_elements_selector, this._validateDom).each(function() {
51 if(!theValidator.validateInput.call(theValidator, this)) {
52 validated = false;
53 };
54 });
55 returnvalidated;
56 },
57 validateInput: function(elem, event) {
58 varinput = $(elem);
59 varclassArr = input.attr('class').split('');
60
61 varvalidated = true;
62 varinValidTable = new Hashtable();
63 for(var i = 0; i < classArr.length; i++) {
64 varclassItem = classArr[i];
65 if(!classItem.startWith('jq-validation')) continue;
66 varvalidateItem = this._validateColl[classItem];
67 if(validateItem && validateItem.validFunc) {
68 if(!validateItem.validFunc(input, validateItem)) {
69 validated = false;
70 if (!strPopupErr.isNullOrEmpty()) {
71 strPopupErr += "";
72 }
73 inValidTable.add(classItem, validateItem);
74 }
75 }
76 }
77 returnvalidated;
78 }
79 };
80 })();
81 //调用例子:
82 <html>
83 <div id="validation_region">
84 < input type="text"class="jq-validation-required"/>
85 < input type="text"class="jq-validation-email"/>
86 </div>
87 < input type="button"onclick="submit()"/>
88
89 <script language="javascript"type="text/javascript">
90 var validator = new Validator("#validation_region");
91 function submit(){
92 if(validator.validate()){
93 alert('验证通过!');
94 }else{
95 alert('验证失败!');
96 }
97 }
98 </script>
99 </html>

解释:

1.设计思想

其中Validation 可以定义和扩展各种验证规则的方法,而Validator则负责处理验证后的错误提示以及如何正确反馈给代码调用者是否验证通过, Validation.validateColl则定义了哪种类型的验证调用哪一个验证规则的处理方法,他们各自分工明确,这也符合单一职责的设计原则。以上代码中我们可以看到Validation 对象是实现类,而Validator 对象是修正抽象化类, 而Validation.validateColl则是桥接器(在经典的Gof 23模式中没有这个定义)。当然在这里我们已经不能完全按照设计模式中定义的术语来描述以上代码了。我们只是按照设计模式的思路和理念来设计和构造我们的代码。 

2.工作原理

在调用的例子中:

var validator = newValidator("#validation_region");    

当页面加载完成后我们首先实例化Validator对象并传入需要验证的范围(Scope), 在这里我们传入需要验证区域的ID, 我们利用jQuery的$() 方法来把选择符“#validation_region"转换成可操作的DOM对象. 

当Button 点击时我们调用submit方法,这时执行validator.validate 方法,这个方法会利用jQuery的each方法遍历验证范围内的所有input 控件进行验证,并最终返回验证的结果。 

在Validate的内部方法中我们还可以加入当验证未通过时对input 进行改变样式并错误提示的功能,一般作法是在input加上红色的边框以提示用户,在这里这个功能需要读者根据项目的需求自己进行扩展了微笑.

3.扩展验证规则

前面我们讲解了设计思想以及工作原理,那么我们如何对validation 进行扩展呢?

我们只需要增加新的验证规则方法到Validation对象上,并在Validation.validateColl 对验证类型(input 的class 名)和新的验证规则进行桥接。

例如:

如果我们要加入一个验证是否是数字的规则,我们需要在Validation 对象中加入

number:function (elem) {

    return!isNaN($(elem).val());

}

并在Validation.validateColl中加入

'jq-validation-number': { validFunc:Validation.number, ErrMsg: 'Notnumber’ }

这时我们并不需要更改任何Validator的代码就可以在input 的class中加入’jq-validation-number’ 来进行数字规则验证了。 

这里需要说明一点如果需要对一个input 进行多种验证规则可以在class中以空格分割写入多种验证规则的名称

例如:

<input type="text" class="jq-validation-requiredjq-validation-number"/>  

注:图片引自博客园吕震宇的设计模式系列,另附引用地址可以更详细的了解桥接模式:

http://www.cnblogs.com/zhenyulu/articles/62720.html 



转载请注明出处:http://www.cnblogs.com/RobbinHan/archive/2011/12/05/2270707.html 

本文作者: 十一月的雨 http://www.cnblogs.com/RobbinHan


原文地址:https://www.cnblogs.com/RobbinHan/p/2259812.html