Ввод информации учеником


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

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

  System.out.println("Adding a Pupil...");


  String AddPupilSubj;
  do {

      UserInput.prompt("\nEnter the Subject Code to add the Pupil to, or enter 'list' to list all Subjects: ");
      AddPupilSubj = UserInput.readString();

      if(AddPupilSubj.equals("list"))
        school.listSubjects();

  } while(AddPupilSubj.isEmpty() || AddPupilSubj.equals("list"));


  Boolean found = false;

  // Locate the Subject   
  for(Object obj : school.getSubjects()) {
      Subject subj = (Subject) obj;

      if(subj.getCode().equals(AddPupilSubj)) {

        found = true;

        // Get the ID of the Pupil
        UserInput.prompt("Enter Pupil ID: ");
        int id = UserInput.readInt();

        // Get the Pupil's Name
        UserInput.prompt("Enter Pupil Name: ");
        String name = UserInput.readString();

        // Get the Address of the Pupil
        UserInput.prompt("Enter Pupil Address: ");
        String address = UserInput.readString();

        String date; Boolean valid;
        do {

             // Get the Pupil's Date of Birth
            UserInput.prompt("Enter Pupil Date of Birth (dd/mm/yyyy): ");
            date = UserInput.readString(); 

            valid = validDOB(date);

        } while(!valid);


        // Get the Pupil's email address
        UserInput.prompt("Enter Pupil Email: ");
        String email = UserInput.readString();


        DateTime dob = DateTime.forDateOnly(Integer.parseInt(date.substring(6, 10)), 
                  Integer.parseInt(date.substring(3, 5)),
                  Integer.parseInt(date.substring(0, 2)));

        DateTime admitted = DateTime.today(TimeZone.getDefault());


        Pupil Pupil = new Pupil(id, name, address, dob, email, admitted);
        if(subj.addPupil(Pupil)) {

             System.out.println(
                 String.format("\nPupil, %s, has been added to the %s Subject.", 
                               Pupil.getName(), 
                               subj.getName()));  

        } else {

             System.out.println(
                 String.format("Pupil #%s is already in the Subject!", 
                               Pupil.getID()));

        }


        break;   
      }


  }


  if(!found) {
      System.out.println(
        String.format("A Subject with code, %s, doesn't exist!", 
          AddPupilSubj));
  }


727
3
задан 18 ноября 2011 в 03:11 Источник Поделиться
Комментарии
5 ответов

Функция очень длинная.

Функции должны сделать одну вещь, сделать ее полностью, и делать это хорошо. Длинные функции трудно рассуждать об.

Перенести тему и ученик ввода данных на отдельные функции, чтобы изолировать функции и оптимизации магистральной код.

Я предполагаю, что наличие строки getSubjectCode() и ученик getPupilInformation() методы, каждый из которых содержит в мега-функции.

Соглашения об именовании

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

Использовать типизированные коллекции

Школа.getSubjects() должна возвращать список (или сбора). (Или, по крайней мере, правильно типизированный массив; ничего с объектов.)

Уменьшить количество кода в условные

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

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

В таких случаях, могли бы также сделать отрицательный тест и дальше, слегка "уплощение" петля кишки. (Код оказалась на его стороне-это не график, как все замечательно ;)

Что сказал, Эта функция доступна в содержит метод--зацикливание в магистрали кода не требуется. Видеть рядом.

Локализация функций

Решив, если школа имеет данную тему следует перенести в школьный класс, например:

public class School {
// ... existing functionality elided ...

/** Returns subject with given code, or null if not found. */
public Subject findSubjectByCode(String code) {
for (Subject s : subjects) {
if (s.getCode().equals(code)) {
return s;
}
}
return null;
}
}

Переработанная магистральных код

Все вышесказанное превращает магистральный код на следующий:

System.out.println("Adding a Pupil...");

String subjectCode = getSubjectCode();
Subject schoolSubject = school.findSubjectByCode(subjectCode);
if (schoolSubject == null) {
System.out.printf("A Subject with code, %s, doesn't exist!%n", subjectCode);
return;
}

Pupil pupil = getPupilInformation();
if (schoolSubject.addPupil(pupil)) {
System.out.printf("%nPupil, %s, has been added to the %s Subject.%n", pupil.getName(), subj.getName());
} else {
System.out.printf("Pupil #%s is already in the Subject!%n", pupil.getID());
}

ИМО это более общительный, чище и проще для понимания.

7
ответ дан 20 ноября 2011 в 07:11 Источник Поделиться

Много работы здесь делать! Я постараюсь, чтобы вы начали на рефакторинг этого:

Прояснить Ваши Намерения

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

Один из способов извлечь свой класс и имена методов-это изучение журналов или println по.


"Добавление ученика..."

А-ХА! Так что ваш первый шаг должен сделать класс под названием "Ученик" и метод "добавить" (или "addPupil"). Убедитесь, что метод "добавить", добавляет ученика к списку объектов учеником.

Примечание: Если вы получаете странное ощущение "добавление ученика, чтобы ученик" и, как это ни странно, принять к сведению и вернуться к нему позже, потому что мы еще не закончили! (т. е., Возможно, есть немного больше абстракции, чтобы найти...)

Экстракт Классов

Цель здесь заключается в создании соответствующих абстракций. Одним из руководящих принципов, вы можете использовать один принцип ответственности, в классе должно быть ни одной причины, чтобы изменить. Я собираюсь продолжить поиск/комментарии свои запросы за возможные намеки.


  • Я вижу "введите код предмета" в командной строке. Итак, теперь у вас есть класс тему! (уже есть? здорово!)

  • Добавьте следующие поля для ученика: int идентификатор, строка "имя", строки "фамилия", строку адрес*, строк* dateOfBirth.

  • Я вижу операции по переменной школу еще никто не определил. Возможно, есть предмет в школе? Так что теперь мы можем перенести список учащихся в школу.

*Адрес должен быть отдельный класс с отдельными полями для street1, street2, город, штат и почтовый индекс.

*в конечном счете преобразовать dateOfBirth в формате даты, я вижу вы используете Датавремя.

Переместить Логику В Классы

Сделать методы из существующих условий и места в соответствующем классе. Если у вас нет класса, чтобы он соответствовал, сделать новый класс.

Например, этот фрагмент кода может быть инкапсулирована в метод:

Датавремя createDateOfBirth (дата, строка)

DateTime dob = DateTime.forDateOnly(Integer.parseInt(date.substring(6, 10)), 
Integer.parseInt(date.substring(3, 5)),
Integer.parseInt(date.substring(0, 2)));

Мелкие подчистки

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


  • "Строки AddPupilSubj" должны быть в нижнем регистре. Возможно, что эта жизнь слишком долго, а также.

  • Изменить "если(AddPupilSubj."равно" ("список"))":


    1. изменения в "список".равна(AddPupilSubject)

    2. добавить AddPupilSubject.столоверчением (), поскольку вы сравниваете его в "список".

    3. возможно, вызов AddPupilSubject.отделка() и удалить любой пробел так что если кто-то вошел в "список ", ваша функция будет работать.


6
ответ дан 28 ноября 2011 в 05:11 Источник Поделиться

Мне кажется, что у вас есть пару функций, вот что нужно вытащил:


  1. findSubject

  2. сбор информации и проверка

    • Я также вытащить функции для все более активное участие как дата подсказывает, что нужно проверить


  3. создание учеником и добавить

Другие вопросы:


  • есть другие места, которые ученик получает входной сигнал? следует избегать дублирования этого кода

  • почему записка validDob возвращать допустимый Добролюбов вместо того, чтобы иметь две разных версии этот код 1) Проверка, 2) преобразуется в объект Date

3
ответ дан 18 ноября 2011 в 04:11 Источник Поделиться

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

1
ответ дан 18 ноября 2011 в 04:11 Источник Поделиться

Я хотел извлечь из ввода/вывода логики обработки в UserInputOutput интерфейс:

public interface UserInputOutput {

String readCommand();

int readPupilId();

String readPupilName();

String readPupilAddress();

Date readPupilBirthDate();

...
}

затем создайте ConsoleUserInputOutput класс, который реализует интерфейс и передать ссылку на код.

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

0
ответ дан 29 ноября 2011 в 09:11 Источник Поделиться