强制对象按顺序运行/执行方法

时间:2013-11-12 14:58:00

标签: c# design-patterns

我有一个接受多个集合的类,然后需要按特定顺序对这些集合执行计算。 E.G。

public class ClassCalc
    {
        public ClassCalc(double varEm, 
                          List<List<double>> col1, 
                          List<List<double>> col2)
        {
          //set fields etc.
        }

        public void CalcCols(){
           //here, I will 'zip' col1/col2 to create List<double> for each
        }

        public void CalcStep2(){
           //this is dependent on the results from CalcCols()
        }

        public void CalcNonDependent(){
           //this can be called at any stage
        }
}

构造函数强制客户端提供相关数据,因此通过调用constructor中的方法,有明显的方法可以做到这一点,这样,我知道所有内容都会被填充。但是,这似乎不是一个干净的解决方案,特别是当我想对代码的一部分进行单元测试时。

如果我想进行单元测试CalcNonDependent(),我需要完全初始化对象,当我甚至不需要其他两个计算的结果时。

所以,我的问题是,是否存在可用于此特定场景的模式;我看过Chain of Responsibility&amp; Command Pattern,但想知道是否有人有任何建议

5 个答案:

答案 0 :(得分:7)

你看过模板吗?不确定它是否适用于您的情况100%,但您将拥有一个定义3个抽象方法的基类,然后以正确的顺序调用它们。

class SomeBaseClass
{
    public abstract void CalcCols();

        public abstract void CalcStep2();

        public abstract void CalcNonDependent();

    public void DoAllCalculations() 
    {
        CalcCols();
        CalcStep2();
        CalcNonDependent();
    }
}

然后从这个类继承并提供计算方法的具体实现。

答案 1 :(得分:4)

我建议专注于代码覆盖而不是方法覆盖。这样,您可以将方法设为私有,并公开一个方法,该方法调用所有3个方法,为类提供100%的覆盖率。如果您担心出于性能原因而划分测试,那么您可以进一步将测试细分为每天执行夜间长时间运行测试的组和每次检查测试。

命令模式不会在使类更具可测性的方式上解决太多问题。如果你需要运行时工作流程适应(E.G. M1(),M2(),然后M2(),M1(),然后是M2(),M3()等),我会使用这样的模式。

例如,

public class ClassCalc
    {
        public ClassCalc(double varEm, 
                          List<List<double>> col1, 
                          List<List<double>> col2)
        {
          //set fields etc.
        }

        public void DoWork()
        {
             //Run methods in order.
        }

        private void CalcCols(){
           //here, I will 'zip' col1/col2 to create List<double> for each
        }

        private void CalcStep2(){
           //this is dependent on the results from CalcCols()
        }

        private void CalcNonDependent(){
           //this can be called at any stage
        }
}

答案 2 :(得分:1)

你似乎从无到有地制造了一个复杂的问题。只需将课程更改为:

public class ClassCalc
{
    public ClassCalc(double varEm, 
                     List<List<double>> col1, 
                     List<List<double>> col2)
    {
        //set fields etc.
    }

    public void CalcCols()
    {
       //here, I will 'zip' col1/col2 to create List<double> for each
       CalcStep2();
    }

    public void CalcNonDependent()
    {
       //this can be called at any stage
    }

    private void CalcStep2()
    {
    }
}

答案 3 :(得分:1)

如果对于CalcStep2,必须执行CalcCols,为什么不保留一个标记来跟踪它,并在CalcStep2中包含类似

的内容
if (!CalcColsHasBeenDone)
  CalcCols();

当然,不要忘记在CalcCols结束时将CalcColsHasBeenDone设置为true:)

答案 4 :(得分:0)

您可能希望为公共操作提取接口,并仅通过它公开单个公共方法。

与此结合使用P.Brian.Mackey's answer将使客户端视图中的其他方法不可见,而它们仍然可以在实现类中公开,从而允许在需要时进行单元测试。