在我的当前项目中,有一些类需要验证电子邮件/网站地址。实现这个功能的方法都相同。
我想知道最好的实现方式是什么,这样我就不需要把这些方法到处复制粘贴了。
这些类本身并不一定相关,它们只是具有这些验证方法的共同点。
在我的当前项目中,有一些类需要验证电子邮件/网站地址。实现这个功能的方法都相同。
我想知道最好的实现方式是什么,这样我就不需要把这些方法到处复制粘贴了。
这些类本身并不一定相关,它们只是具有这些验证方法的共同点。
加入一个接口,然后使用扩展方法怎么样?
public interface IFoo { }
public class A : IFoo {}
public class B : IFoo {}
public class C : IFoo {}
public static class FooUtils {
public static void Bar(this IFoo foo) { /* impl */ }
}
这样做的好处:
您可能希望将所有验证代码放入一个名为Validator的类中,然后在需要进行验证的任何地方使用该类。访问验证应通过单个方法Validate(object Something)
进行。我认为这被称为“组合”(就设计模式而言)。
稍后,您可以拥有更具体或执行不同类型验证的Validator子类。
您还可以使所有需要验证的类扩展一个具有90%验证内容的基类或抽象类。
public static class Utilities{
public static bool validEmail(string email)
{
//Your code here
}
}
是的,复制这段代码会产生不好的代码气味。你可以将这些方法提取到一个单独的 Helper 类中作为静态方法,或者定义一个“验证器”接口类,并使用该接口将不同的验证方法与责任链模式链接起来。
http://msdn.microsoft.com/en-us/library/dd140045.aspx
这个框架允许您为电子邮件验证编写一个单一的处理程序类。这意味着验证代码放入处理程序类中,而不再是类的一部分。接下来要做的事情是标记要拦截的类。
您可以以多种方式拦截类,包括在所需方法上设置属性,以便根据您的要求进行拦截和处理。设置属性可能是执行拦截的最简单方法。
public interface IValidator {
bool CanValidateType(string type);
bool Validate(string input);
}
CanValidateType() 方法可能会更加复杂,但我希望你能理解它的基本思想。它主要是识别验证器是否能够处理所提供的输入。以下是一些实现方式:
public class UrlValidator : IValidator {
bool CanValidateType(string type) {
return type.ToLower() == "url";
}
bool Validate(string input) {
/* Validate Url */
}
}
public class EmailValidator : IValidator {
bool CanValidateType(string type) {
return type.ToLower() == "email";
}
bool Validate(string input) {
/* Validate Email */
}
}
public class SomeSimpleClass {
private IValidator validator;
public SomeComplexClass(IValidator validator) {
this.validator = validator;
}
public void DoSomething(string url) {
if (validator.CanValidateType("url") &&
validator.Validate(url))
/* Do something */
}
}
public class SomeComplexClass {
private List<IValidator> validators;
public SomeComplexClass (List<IValidator> validators) {
this.validators = validators;
}
public bool ValidateUrl(string url) {
foreach (IValidator validator in this.validators)
if (validator.CanValidateType("url"))
return validator.Validate(url);
return false;
}
public bool ValidateEmail(string email) {
foreach (IValidator validator in this.validators)
if (validator.CanValidateType("email"))
return validator.Validate(email);
return false;
}
}
然后,您将不得不以某种方式将所需的验证器实例传递给您的类。这通常使用IoC容器(如Castle Windsor)完成,或者自己动手。
IValidator emailValidator = new EmailValidator();
IValidator urlValidator = new UrlValidator();
SomeSimpleClass simple = new SomeSimpleClass(urlValidator);
SomeComplexClass complex = new SomeComplexClass(new List<IValidator> { emailValidator, urlValidator });
SomeSimpleClass simple = container.Resolve<SomeSimpleClass>();
SomeComplexClass complex = container.Resolve<SomeComplexClass();
所有接口的映射都在您的 app.config 或 web.config 中完成。
这里有一个关于依赖注入和 Castle Windsor IoC 容器的绝妙教程。
Email
的独立类。Email
作为属性/参数/返回值,而不是 String
。EmailValidator
的类来验证字符串是否为电子邮件地址。EmailFactory
的类,当传递有效的电子邮件地址时返回 Email,否则返回 null。