Если методы класса принимают параметры или используют свойства класса

Рассмотрите следующий класс

public class Class1
{
    public int A { get; set; }
    public int B { get; set; }

    public int GetComplexResult()
    {
        return A + B;
    }
}

Для использования GetComplexResult, потребитель этого класса должен был бы знать для установки A и B прежде, чем назвать метод. Если GetComplexResult доступы много свойств для вычисления его результата это может привести к неправильным возвращаемым значениям, если потребитель не устанавливает все соответствующие свойства сначала. Таким образом, Вы могли бы записать этот класс как это вместо этого

public class Class2
{
    public int A { get; set; }
    public int B { get; set; }

    public int GetComplexResult(int a, int b)
    {
        return a + b;
    }
}

Таким образом, вызывающая сторона к GetComplexResult вынужден передать во всех необходимых значениях, гарантировав, что значение ожидаемого дохода правильно вычисляется. Но если существует много необходимых значений, список параметров растет также, и это не походит на хороший дизайн также. Это также, кажется, повреждает точку инкапсуляции A, B и GetComplexResult в едином классе. Я мог бы даже испытать желание сделать GetComplexResult статичный, так как это не требует, чтобы экземпляр класса сделал свою работу. Я не хочу обходить создание набора статических методов.

Там называет, должны описать эти 2 различных способа создать классы? У них обоих, кажется, есть за и против - там что-то, что я не понимаю, что это должно сказать мне, что один путь лучше, чем другой? Как поблочное тестирование влияет на этот выбор?

5
задан kenwarner 5 March 2010 в 19:39
поделиться

3 ответа

Если вы воспользуетесь реальным примером, ответ станет более ясным.

public class person
{
    public string firstName { get; set; }
    public string lastName { get; set; }

    public string getFullName()
    {
        return firstName + " " + lastName;
    }
}

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

Если определенные свойства необходимы сущности, выполняющей свою работу, они могут быть инициализированы в конструкторе. Другой подход - иметь логическое значение, которое проверяет, находится ли объект в состоянии, в котором может быть вызван данный метод:

while (person.hasAnotherQuestion()) {
  person.answerNextQuestion();
}
5
ответ дан 14 December 2019 в 13:33
поделиться

Хорошее правило проектирования - убедиться, что все конструкторы инициализируют объекты в допустимые состояния и что все установщики свойств и методы затем обеспечивают правильное состояние. Таким образом никогда не будет никаких объектов в недопустимом состоянии.

Если значения по умолчанию для A и B , которые равны 0, не являются допустимым состоянием, которое дает допустимый результат из GetComplexResult , вы должны создать конструктор который инициализировал A и B для проверки состояния.

1
ответ дан 14 December 2019 в 13:33
поделиться

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

Например:

public Builder {
    private int a;
    private int b;

    public Class1 create() {
        // some validation logic goes here
        // to make sure we have everything and
        // either fill in defaults or throw an error
        // if needed
        return new Class1(a, b)
    }

    public Builder a(int val) { a = val; }
    public Builder b(int val) { b = val; }
}

Этот Строитель затем можно использовать следующим образом.

Class1 obj1 = new Builder().a(5).b(6).create();

Builder builder = new Builder();
// do stuff to find value of a
builder.a(valueOfA);
// do stuff to find value of b
builder.b(valueOfB);
// do more stuff
Class1 obj2 = builder.create();
Class2 obj3 = builder.create();

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

0
ответ дан 14 December 2019 в 13:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: