链式API
经过改进之后,我们对于“年龄”文本框的判断便可以写成这样了:
<span>Age: </span> <!-- 必填,15到28之间的数字 -->
<input type="text" name="user.Age" />
<% JQuery.Validate().Required("user.Age", null); %>
<% JQuery.Validate().Number("user.Age", null); %>
<% JQuery.Validate().Range("user.Age", 15, 28, null); %>
这里的“坏味道”其实也非常浓郁:为什么user.Age重复了三遍呢?而JQuery.Validate()前缀也反复出现,这也违反了DRY原则,这并不是我们的目的,我们使用编写一套易于使用,流畅的API。说到“流畅”,“链式API”便是其中的典型之一。例如我们在使用StringBuilder的时候,其实便可以使用链式API来拼接字符串:
StringBuilder builder = new StringBuilder();
builder
.Append("Hello ")
.AppendLine("World")
.AppendFormat("{0} {1}", "Hello", "World");
编写这种类型的API其实非常容易,只要每个方法都“返回当前对象”便可(或者可以进行后续操作的新对象)。再考虑到我们需要“定义一个元素”然后“多次使用”以避免反复,我们便可以构造一个新的类型辅助验证信息的收集:
public class JQueryValidation
{
...
public ValidationElement Element(string name)
{
return new ValidationElement(name, this);
}
public class ValidationElement
{
internal ValidationElement(string name, JQueryValidation validation)
{
this.Name = name;
this.Validation = validation;
}
public string Name { get; private set; }
public JQueryValidation Validation { get; private set; }
...
}
}
我们为JQueryValidation定义了一个内部类ValidationElement,并提供一个Element方法用于返回一个ValidationElement对象。在ValidationElement对象内部将保留元素的name以及用于收集信息的JQueryValidation对象。这样我们可以在ValidationElement内部重新定义一些验证方法,并且将调用直接委托给JQueryValidation对象上的方法。当然,每个方法最终还是会把当前ValidationElement对象返回,以便形成链式调用方式:
public class ValidationElement
{
...
public ValidationElement Required(string message)
{
this.Validation.Required(this.Name, message);
return this;
}
public ValidationElement Email(string message)
{
this.Validation.Email(this.Name, message);
return this;
}
public ValidationElement Number(string message)
{
this.Validation.Number(this.Name, message);
return this;
}
public ValidationElement Range(int min, int max, string message)
{
this.Validation.Range(this.Name, min, max, message);
return this;
}
}
看看结果:
<span>Age: </span> <!-- 必填,15到28之间的数字 -->
<input type="text" name="user.Age" />
<% JQuery.Validate().Element("user.Age")
.Required(null)
.Number(null)
.Range(15, 28, null); %>
感觉如何?
多跨一步
不知您是否想到,其实这两篇文章中编写的辅助方法并非ASP.NET MVC转述,因为ASP.NET MVC使用WebForm来作为默认的视图,因此这些方法都可以轻而易举地用在WebForm模型中。我们唯一需要的就是……要不您自己思考一下?:)
总结
每个优秀的项目都会有一套完备的辅助方法类库来简化开发,这套类库随着项目的进行会不断完善,不断丰富。在编写辅助方法时,有时候会需要您尽可能地想象,不拘一格,唯一的目的便是优美易用的API
原文地址:http://www.cnblogs.com/jeffreyzhao/archive/2009/04/29/custom-view-helpers-2.html