2012-09-05 205 views
1

我希望能够收集几个验证实体,全部共享相同的接口。这是我想出了:Multipe策略设计模式

public interface Ivalidateable 
{ 
    bool IsValid(IValidateParam param); 
} 

public interface IValidateParam 
{ 

} 

public abstract EmployeeStrategy: Ivalidateable 
{ 
    public abstract bool IsValid(User user); 
} 

public abstract SpreadStrategy: IValidateable 
{ 
public abstract bool IsAvlid(Campaign campaign); 
} 

public class User: IValidateParam 
{} 

public class Campaign: IValidateParam 
{} 

public EmployeeTypeStragtegy: EmployeeStrategy, IValidateable 
{ 
public bool IsValid(User user) 
{ 
    if (new[]{'e',a','b}.Contains(user.userId.first().toString())) 
    return true; 

    return false; 
} 
} 

public TrailSpreadStrategy: SpreadStrategy, IValidateable 
{ 
public bool IsValid(Campaign campaign) 
{ 
    //logic goes here 
} 
} 

public EvenpreadStrategy: SpreadStrategy:, IValidateable 
{ 
public bool IsValid(Campaign campaign) 
{ 
    //logic goes here 
} 
} 

public class ValidationFactory 
{ 
private static List<IValidateable> stragtegies; 

static ValidationFactory 
{ 
    strategies = new List<IValidateable>(); 
    strategies.Add(new EmployeeTypeStragtegy()); 
    strategies.Add(new TrailSpreadStrategy()); 
} 

public bool IsValid(//Need to pass User/Campaign) 
{ 
    //what do I do here? 
} 
} 

什么是通过用户/活动,使我可以循环策略和检查IsValid的最佳方式是什么?

+0

您有两种验证活动的策略,都会执行还是有一些标准来选择正确的策略? –

+0

每个类型只会有一个(用户/广告系列)...我只想显示声明多个的想法 –

回答

2

以下是我会做:

// campaign object class, and it's separate validator logic 

public class Campaign 
{ 
} 

public class CampaignValidator : IValidationStrategy<Campaign> 
{ 
    public bool IsValid(Campaign test) 
    { 
     return true; 
    } 
} 

// framework stuff 

public interface IValidationStrategy<T> 
{ 
    bool IsValid(T test); 
} 

public static class ValidationFactory 
{ 
    private readonly static Dictionary<Type, object> _typeValidators; 

    static ValidationFactory() 
    { 
     _typeValidators = new Dictionary<Type, object>(); 
     _typeValidators[typeof(Campaign)] = new CampaignValidator(); 
    } 

    public static bool IsValid<T>(T obj) 
    { 
     return ((IValidationStrategy<T>)_typeValidators[typeof(T)]).IsValid(obj); 
    } 
} 

之后,你可以调用ValidationFactory.IsValid(myObject);,如果类型是在厂里静态构造函数,它会给你真/假。

验证工厂正在做一种DI/IOC的事情,即您可以使用Ninject,Castle等实现将类型映射到验证器类型。

您可以动态地或不同地执行任何操作,而无需以相同的方式构建字典 - 查看验证程序实现的接口的泛型类型参数,或者搜索基于IValidationStrategy<>的类并再次查看泛型类型参数。但上述内容快捷简单。

是否有你想单独验证器类的原因?

+0

我想分开他们,因为每个人都得到一个不同的对象来验证 –

+0

是的,我明白了,但为什么不包括一个IsValid对每个对象本身? :) –

+0

我想我得到你了!谢谢!我想循环遍历它们并为每个策略调用IsValid,这就是为什么我为每个策略都有IsValid。 –

0

这个怎么样?

更改所有的IsValid使用这台样机(用户用户,竞选活动),例如:

public EmployeeTypeStragtegy: EmployeeStrategy, IValidateable 
{ 
public bool IsValid(User user, Campaign campaign) 
{ 
    return (new char[]{'e','a','b'}.Contains(user.userId.first().toString()); 
} 
} 

然后处理由相应的各类型,这样,他们都接受相同的参数。然后:

public bool IsValid(User user, Campaign campaign) 
{ 
    bool valid; 

    foreach (IValidateable iv in strategies) 
    { 
     if (!iv.IsValid(user, campaign)) 
      valid = false; 
    } 

    // This returns true if all are valid, false if not (not sure if this is the logic you expect) 
    return valid; 
} 
+0

我想要这样做: public bool IsValid(User user,Campaign campaign) { return strategies.All(s => s.IsValid(// ???)) } –

+0

因此,您希望提供1个用户和1个广告系列并循环访问所有策略,以查看它们是否对任何一个有效类型? – crlanglois

+0

准确地crlangois !!!如果策略是基于员工,它将使用该用户,如果它是SpreadStrategy,它将使用活动 –

0

我建议看看FluentValidation的嵌套和收集验证功能。如果没有额外的工厂和接口,这应该可以正常工作 - 如果您的策略持有对您想与其一起验证的其他实体的引用。