Проверка аргументов метода - PullRequest
0 голосов
/ 28 июля 2010

У меня есть вопрос о наилучшей практике для проверки аргументов метода, когда аргументы содержатся в объекте.Например, если у вас есть:

public class Student {
   public int getStudentId();

   public String getStudentName();

   public String getStudentSSN();

   public double getStudentGpa();

   public String getStudentMajor();

   // Other student related getters
}

Затем у меня есть метод:

public void printStudentReport(Student student);

В этом методе мне нужно выполнить логику, включающую идентификатор, имя, GPA иосновной.Итак, это те, которые необходимы.Все остальные студенты-получатели не должны быть заселены.Можно ли сначала просто проверить объект Student, а затем те четыре метода, которые мне нужны?Я чувствую, что это немного вводит в заблуждение, потому что я передаю этот объект Student этому методу, но не все поля обязательны для заполнения, так что этот метод действительно наполовину заполнен.Просто кажется мне странным.

Ответы [ 7 ]

2 голосов
/ 28 июля 2010

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

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

1 голос
/ 28 июля 2010

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

Теперь проверка более сложна.Нужен ли для отчета специальный вид проверки, отличный от обычного для студентов?Если это так, то непременно проверьте его в отчете:

public void printStudentReport(Student student) {
  validateStudent(student);
  // print the report....
}

Но если проверка является общей для набора клиентов (возможно, для printStudentReport и для saveStudentInDatabase), тогдаВы можете создать класс проверки:

public class FloogleStudentValidator { // or some good name that tells us what this validation does
  public void validate(Student student) { }
}

// ...

public void printStudentReport(Student student) {
  new FloogleStudentValidator().validate(student);
  // print the report....
}

У вас будут разные классы для разных типов проверки учащихся.

Но если проверка является общей для всей системы, чем яЯ бы предпочел поместить его в класс Student или проверить его, так как он заполнен в экземпляре студента.

public void printStudentReport(Student student) {
  student.validate();
  // print the report....
}
0 голосов
/ 28 июля 2010

Один вопрос, который возникает у меня, заключается в том, действительно ли логика является логикой отчета или логикой ученика.В отчете вы можете указать:

  thing = (student.getX() + student.getY() ) * student.getZ();

или просто

  thing = student.getThing();

Я предполагаю, что, вероятно, некоторые вещи принадлежат учащемуся.что мы не можем вычислить вещь , потому что некоторые из X, Y или Z неправильно инициализированы.Поэтому вызов getThing () может вызвать исключение, но это кажется странным.Почему объект должен предлагать некоторую возможность getThing (), но не может это сделать?

Мне кажется, что ваш класс Student нуждается в рефакторинге.Студенты могут использовать основной набор возможностей, и их достаточно, чтобы можно было составлять определенные отчеты.Следовательно, у вас есть, скажем, IRegistered интерфейс и более богатый интерфейс IActiveStudent.Вашему классу отчетов требуется IRegistered, а другим классам нужен IActiveStudent.

Различные объекты Student изменяют свои возможности в течение своей жизни, подобно тому, как Caterpiller превращается в мотылька.У вас нет метода fly () для гусеницы, и, следовательно, вам не нужен метод canYouFlyYet () для всех ваших классов чешуекрылых.

0 голосов
/ 28 июля 2010

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

public void printStudentReport(MyInterface student)

интерфейс может содержать метод проверки

0 голосов
/ 28 июля 2010

Наполовину заселенные объекты встречаются довольно часто. Особенно, если у вас нет контроля над источником данных, заполняющим ваши объекты. Я говорю, что было бы просто хорошо проверить только те поля ученика, которые необходимы для printStudentReport (). Я часто пишу аналогичные методы генерации отчетов, которые проверяют на основе необходимых данных, но предоставляют дополнительные данные из объекта, если он присутствует.

0 голосов
/ 28 июля 2010

Один из вариантов заключается в том, чтобы объект Student проверял создание своих данных на основе (и во время редактирования), поэтому при передаче объектов Student вы всегда можете быть уверены, что они допустимы.

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

0 голосов
/ 28 июля 2010

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

Таким образом, вы отделяете метод печати от Student со всеми вытекающими отсюда преимуществами.

...