我目前的项目中有几个课程,需要验证电子邮件/网站地址。这样做的方法都是一样的。
我想知道实现这个的最佳方法是什么,所以我不需要将这些方法复制到任何地方?
这些类本身并不一定相关,它们只有那些共同的验证方法。
答案 0 :(得分:17)
添加界面和使用扩展方法怎么样?
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 */ }
}
那样:
答案 1 :(得分:7)
您可能希望将所有验证代码放入Validator类中,然后在需要验证的任何位置使用该类。访问验证应该通过单一方法,Validate(object Something)
。我认为这被称为“组合”(就设计模式而言)。
稍后,您可以将Validator的子类更具体或进行不同类型的验证。
您还可以让所有需要验证的类扩展一个基类或抽象类,其中包含90%的验证。
答案 2 :(得分:5)
听起来你只需要一个带静态方法的静态类
public static class Utilities{
public static bool validEmail(string email)
{
//Your code here
}
}
答案 3 :(得分:2)
是的,重复这段代码会很难闻,你可以在静态方法中将这些方法提取到单个Helper类,或者你可以定义一个“Validator”接口类并使用这个接口,你可以链接不同的验证方法。责任模式。
答案 4 :(得分:1)
创建一个Utility类,并将这些方法定义为适当的类/接口的扩展方法。
答案 5 :(得分:1)
您真的需要仔细研究面向方面的编程方法(AoP)。 Enterprise Library 4.1有一个名为Unity Interception的AoP实现。
http://msdn.microsoft.com/en-us/library/dd140045.aspx
此框架允许您为电子邮件验证编写单个处理程序类。所以这需要验证代码进入处理程序类,而不再是类的一部分。接下来要做的是标记拦截类。
您可以通过各种方式拦截类,包括根据您的要求设置应该截获和处理的所需方法的属性。设置属性可能是拦截的最简单方法。
答案 6 :(得分:0)
创建验证逻辑类和接口,并将它们注入到代码中......所以将逻辑从验证中分离出来,以便可以重用它......
答案 7 :(得分:0)
创建Email
作为单独的类
在您的班级中使用Email
作为属性/参数/返回值,而不是String
创建EmailValidator
以将字符串验证为电子邮件地址
创建传递有效电子邮件地址时返回电子邮件的EmailFactory
,否则返回null。
(网站也一样)。
答案 8 :(得分:0)
我建议您创建一个IValidator接口,然后创建多个不同的验证器来处理不同的场景。这是一个例子:
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 */
}
}
当你有一个可以使用多个验证器的类时,CanValidateType会派上用场。在这种情况下,您将列表或验证器数组传递给构造函数。
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 });
上面的代码让你自己很烦人,这就是IoC容器如此方便的原因。使用IoC容器,您可以执行以下操作:
SomeSimpleClass simple = container.Resolve<SomeSimpleClass>();
SomeComplexClass complex = container.Resolve<SomeComplexClass();
接口的所有映射都在app.config或web.config中完成。
这是关于依赖注入和Castle Windsor IoC容器的an awesome tutorial。