重构 - 在这个例子中使用哪种模式?

时间:2010-08-12 11:21:36

标签: excel vba refactoring

我有一个处理来自excel文件的行的函数。在这个函数中,我有一个for循环。现在,一旦提取了一行,我们检查各种条件。如果任何条件为假,我们继续下一步row.Can这个代码可以使用模式更加结构化吗?

 foreach (System.Data.DataRow dr in ds.Tables[0].Rows)
                {

                    Product prod = GetProduct(dr);
                    if (prod == null)
                    {
                        IndicateNotInserted(dr, "InvalidProduct");
                        continue; 
                    }



                    if (IsProductExpired())
                    {
                        IndicateNotInserted(dr, "Expired");
                        continue; 
                    }
                    ProcessRow(dr);

4 个答案:

答案 0 :(得分:2)

您可以使用chain of responsibility样式模式,其中有一系列类,每个类负责检查有效性的一个方面并报告错误类型。

你会将Prod传递给检查有效性的第一个类,如果它是无效的,它会报告并返回false。如果它是有效的,它将返回当前实例的后继者的有效性检查(如果它有一个)。

然后您的代码可以获取Prod并将其传递给根有效性检查器,并在报告为false时继续。

这也可以让你以后轻松添加新的验证器,可以在不必重新编译的情况下完成,具体取决于你如何实现验证器链的构建。

类似的东西:(伪代码,未经过测试/编译)

public interface IValidator
{
bool IsValid(Product product);
IValidator Successor{get;set;};
}

public class AbstractValidator : IValidator
{    
    IValidator m_successor=null;
    public abstract bool IsValid(Product product);

    IValidator Successor
    {
    get 
      {
      if(m_sucessor==null)
          return new AlwaysValidSuccessor();
      else
          return m_successor;
      }
    set
       {
       m_successor=value;
       }
    }
}

public class NullValidator : AbstractValidator
{
 public bool IsValid(Product product)
 {
    if (product!=null)
        {
        return Successor.IsValid(product);
        }
    return false;
    }
}

public class ExpiredValidator : AbstractValidator
{
 public bool IsValid(Product product)
 {
    if (product.Expired==false) //whatever you need to do here
        {
        return Successor.IsValid(product);
        }
    return false;
    }
}

然后你使用它:

IValidator validatorRoot = new NullValidator();
validatorRoot.Successor = new ExpiredValidator();
// construct the chain with as many as you need
//then use it
if (validatorRoot.IsValid(Prod)==false)
{
     continue;
}

答案 1 :(得分:1)

解决此问题的最佳方法是定义您的查询,使其不会返回无效和过期的产品。

答案 2 :(得分:0)

您可以使用切换案例吗?

答案 3 :(得分:0)

结合Sam Holder,依赖于你需要这个验证系统的通用性,你可以用Decorator包装任何职责,以便能够使用共同行为包装验证检查,这种行为是联合多次验证检查。 / p>