2

我有一个需要多个集合的类,然后需要以特定顺序对这些集合执行计算。例如

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& Command Pattern,但想知道是否有人有任何建议

4

5 回答 5

8

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

class SomeBaseClass
{
    public abstract void CalcCols();

        public abstract void CalcStep2();

        public abstract void CalcNonDependent();

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

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

于 2013-11-12T15:03:13.217 回答
4

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

命令模式在使类更具可测试性方面不会解决太多问题。如果您需要运行时工作流调整(例如 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
        }
}
于 2013-11-12T15:07:28.633 回答
1

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

if (!CalcColsHasBeenDone)
  CalcCols();

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

于 2013-11-12T15:04:07.037 回答
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()
    {
    }
}
于 2013-11-12T15:02:50.900 回答
0

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

将此与例如P.Brian.Mackey 的答案结合使用将使其他方法从客户的角度来看是不可见的,而它们仍然可以在实现类中公开,从而允许在需要时进行单元测试。

于 2013-11-12T15:09:14.953 回答