如果需要不同数量和类型的参数,如何创建操作代表列表

时间:2011-11-10 21:01:05

标签: c# oop design-patterns

我们有一组大约24个类,它们从一个具有抽象Validate方法的基类继承。当然每个类都有不同的验证需求,但是所有类都需要不同的组合规则,因此,正如您可以想象的那样,这导致了大量代码重复,例如:

A类需要规则1,3,6和9 B类需要规则3,4和8 C类需要规则1,8和9 ....

你明白了。

所以我想做一个简单的重构并创建一个验证装饰器,其中每个规则都封装在一个类和一个工厂中,它将为每个类创建一个adhoc验证组合。

然后我开始认为每个规则都是如此简单,以至于不是为装饰器创建所有管道,而是可能只有Action委托存储在工厂中,这将填充List(Action(T))以便每个类只会迭代通过该列表执行每个代表。

问题是参数的数量和/或类型在每个规则之间有所不同,例如:

规则1需要可以为空的DateTime,DateTime和枚举 规则2需要可以为空的DateTime和DateTime 规则3需要一个字符串.....

这是可以完成的事情,还是我不能选择编码装饰器?

感谢您的想法和想法。

更新 一些规则示例:

if(EndTime.HasValue && StartTime > EndTime)  
     Throw new Exception (...);

if(Status == StatusEnum.Pass && !EndTime.HasValue)  
     Throw new Exception (...);

if(string.IsNullOrEmpty(ProcessName))
     Throw new Exception (...);

if(string.IsNullOrEmpty(ProductName))
   Throw new Exception (...);

if(string.IsNullOrEmpty(CustomerName))
   Throw new Exception (...);

所有涉及的类都包含属性DateTime? EndTimeDateTime StartTimeStatusEnum Statusstring ProcessName

2 个答案:

答案 0 :(得分:1)

首先,您可以创建一个包含所有参数的类,其中布尔值表示哪些是相关的。您也可以创建一个Params委托,但这有点难看(它还要求您将参数转换为对象数组)。

就个人而言,我会选择一个描述所有参数的类。

编辑:

以下是ValiationRuleParameters(包含参数的类)的一个示例:

    public class ValidationRulesParam
{
    private readonly Dictionary<string, object> _parameters = new Dictionary<string, object>();

    public bool AddParam(string name, object value)
    {
        if (!_parameters.ContainsKey(name))
            return false;
        _parameters.Add(name, value);
        return true;
    }

    public bool IsTypedParameterSet(string name, Type valueType)
    {
        object value;
        if (_parameters.TryGetValue(name, out value) == false)
            return false;
        return (value.GetType() == valueType);
    }

    public TValue GetParamValue<TValue>(string name)
    {
        object value;
        if (_parameters.TryGetValue(name, out value) == false)
            return default(TValue);
        if (!(value is TValue))
            return default(TValue);

        return (TValue)value;
    }

    public object this[string name]
    {
        get { return GetParamValue<object>(name); }
        set { AddParam(name, value); }
    }
}

它有点像使用params对象[]和使用普通字典的组合

您可以将此类的实例发送到您运行的每个验证规则(操作),并且阳离子可以测试参数的存在(以及它的类型)。并获得它的价值。

这只是一个例子(并且还有很多需要改进的地方),但它应该能够提供一个表达这个想法的精彩图片。

答案 1 :(得分:0)

为什么不创建一个名为IValidationParameter之类的接口然后让每个验证规则都有一个IValidationParameter的实现。例如

public class Rule1ValidationParameter : IValidationParameter
{
    public DateTime? FirstDate { get; set; }
    public DateTime SecondDate { get; set; }
    pulbic MyEnum MyEnum { get; set; }
}

然后列出您的列表List<Action<IValidationParameter>>

相关问题