首页 > 解决方案 > 类构造函数应该只用于依赖注入吗?

问题描述

类构造函数可以通过两种主要方式填充其类的依赖项:

  1. 通过构造函数依赖注入填充类依赖项。
  2. 通过使用构造函数参数在构造函数中运行一些计算来填充类依赖项。基于计算结果实例化依赖关系。这可能涉及使用new.

我想知道第二种方法是否遵循良好的编码实践,例如单一职责原则,以及这种功能是否真的属于类构造函数。这似乎很方便,但我不确定这是否是个好主意。

这是我的意思的一个例子:

public class VectorSpace
{
    // This class depends on an array of Vectors.
    Vector[] spanningSet;

    // 1. Populate the class dependencies by constructor dependency injection.
    public VectorSpace(Vector[] spanningSet)
    {
        this.spanningSet = spanningSet;
    }

    // 2. Populate the class dependencies by running some calculations in the constructor.
    public VectorSpace(Rect rectangle, int numberOfCellsX, int numberOfCellsY)
    {
        // Construct this class to make sure the resulting vector space fits the given rectangle, forming a grid.
        // Some calculations that ultimately populate the class dependencies go here...
    }

    // Public methods for performing calculations using the Vectors go here...
}

感觉很奇怪,因为让向量空间填充网格感觉像是一项超出了此类范围的工作,但我不知道我还要在哪里定义第二个构造函数。

第二个构造函数的功能是否适合在这个类中?如果没有,我会将这个构造函数体移动到哪里?我应该改用静态工厂方法吗?我应该让这个构造函数成为不同类的构造函数吗?也许我可以在某个地方有一个类似的方法,它返回一个向量数组,我可以将其传递给依赖注入构造函数,但是我将在哪里定义该方法?

标签: c#dependency-injectionconstructor

解决方案


VectorSpace类取决于数据(向量集),但可以通过多种方式提供/计算数据。如果您将改变向量的计算/检索方式
,逻辑会改变吗?VectorSpace我认为不是 - 所以它不应该是VectorSpace课程的一部分。

我们可以创建专门的类来负责计算所需的数据。

public class SpanningSetFactory
{
    public Vector[] Create(Rect rectangle, int numberOfCellsX, int numberOfCellsY)
    {
        // Calculate and return set of vectors
    }
}

现在 VectorSpace 可以明确地“告诉”其他开发人员/读者它只依赖于向量集

public class VectorSpace
{
    public VectorSpace(Vector[] spanningSet) => _spanningSet = spanningSet
}

现在,“计算跨越集”和“使用跨越集”这两个逻辑都将位于它们自己的位置而不相互依赖 - 只有它们相互之间的依赖链接将是数组Vector

我建议避免在构造函数中进行一些计算(尤其是繁重的计算)。
当关键逻辑(计算、数据检索)以方法或其他类型的形式显式可见时,将对其他开发人员有很好的帮助。


推荐阅读