如何构建类以便于消费者和测试人员理解

本文关键字:测试 消费者 何构建 构建 | 更新日期: 2023-09-27 18:20:52

我正在努力找出构建类的最佳方法,以便类的使用者能够以最少的工作量使用它们。

举两个例子:

public class Foo
{
    public List<Bar> Bars { get; private set; }
    public Foo()
    {
        Bars = new List<Bar>();
        Method1();
        Method2();
    }
    private void Method1()
    {
        // code
    }
    private void Method2()
    {
        // code
    }
}

在这种情况下,类的使用者不需要知道如何使用该类,并且(假设方法1/2对Bars执行一些操作)用户只需要实例化该类就可以获得所需的信息-Bars。

或者应该这样做(或者完全不同):

public class Foo
{
    public List<Bar> Bars { get; private set; }
    public Foo()
    {
        Bars = new List<Bar>();
    }
    public void DoStuff()
    {
        Method1();
        Method2();
    }
    private void Method1()
    {
        // code
    }
    private void Method2()
    {
        // code
    }
}

在这种情况下,使用者需要知道如何调用DoStuff()才能正确使用该类。在类变得臃肿的情况下,如果用户需要弄清楚方法的调用顺序,这可能会让用户感到困惑。在这种情况下,我知道在最佳实践中,类应该精简并遵循SRP,但如果不是这样,那么有理由使用一种方法与另一种方法进行比较吗?

与此相关的是,因为我的Method1和Method2在我的Bars中操作数据,是否有一个规则/最佳实践来决定Method1和Method 2是否接受List的参数然后应用于Bars,或者它是否可以直接使用Bars而不将参数带入对象。有理由做一个而不是另一个吗?

如何构建类以便于消费者和测试人员理解

在构造类时,是否有合理的理由调用这两个方法?

是否有正当理由在构建实例后的某个时间点调用这两个方法?

在给定实例上多次调用这些方法是否无效?

如果以上任何一项都是真的,那么该功能在第一个选项中不可用,但在第二个选项中可用。如果该功能实际上很重要,那么第一个选项*就不能提供所需的功能。

如果以上所有问题都是"否",那么第二个问题就不是一个真正的选择。你提供的功能是消费者只能做错事的。他们只是因为没有做正确的事情而破坏了事情,所以你不妨为他们做正确的事,不要给他们犯错的机会。

另一方面,如果第一个选项没有提供所需的功能,但仍然存在某些限制(即无法多次调用它们,但希望尽可能推迟工作,在完成这项工作之前无法调用其他方法,等等),那么两者都有错。您需要非常明确地说明您的实际约束是什么,以及所有必需的(可能也很好)功能是什么,以尝试找到一个满足所有约束的解决方案,同时仍然提供所有必需的功能。

您似乎已经回答了自己的问题。你有没有一个更具体的例子可以更清楚地说明你为什么要考虑第二个例子?

构造函数应该做一切必要的事情来初始化类,以便它可以使用,就像第一个例子一样。由于从用户的角度来看,Bars是只读的,而且显然初始化Bars列表和包含的Bar对象的DoStuff()方法不接受任何参数,因此应该在构造函数中完成。