Должны ли конструкторы классов использоваться только для внедрения зависимостей?

Есть два основных способа, которыми конструкторы классов могут заполнять зависимости своего класса:

  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...
}

Это кажется странным, потому что заполнение сетки векторным пространством напоминает работу, которая выходит за рамки этого класса, но я не знаю, где еще я бы определил этот второй конструктор.

Соответствует ли функциональность второго конструктора тому классу? Если нет, куда бы я переместил это тело конструктора? Должен ли я использовать статический метод фабрики вместо этого? Должен ли я сделать этот конструктор конструктором другого класса? Может быть, у меня мог бы быть где-то похожий метод, который возвращает массив Векторов, которые я мог бы передать в конструктор внедрения зависимостей, но где бы я определил этот метод?

Всего 1 ответ


Класс VectorSpace зависит от данных (набора векторов), но данные могут быть предоставлены / рассчитаны разными способами.
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

Я бы посоветовал не помещать некоторые вычисления (особенно тяжелые) в конструктор.
Хорошей помощью для других разработчиков будет, когда критическая логика (вычисления, получение данных) явно видна в формах методов или других типов.


Есть идеи?

10000