首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >输入瞳孔信息

输入瞳孔信息
EN

Code Review用户
提问于 2011-11-18 15:27:44
回答 5查看 660关注 0票数 3

我有以下代码,它位于一个大小写中,在一个开关语句中。它的目标是在相应的班级中使用集合将一个学生添加到学科中。

我试图使代码尽可能可读性,但我确信有一个更好的方法。

代码语言:javascript
复制
  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));
  }
EN

回答 5

Code Review用户

发布于 2011-11-20 19:23:30

这个函数很长。

函数应该做一件事,完全完成它,并且做好它。长函数是很难推理的。

将主题和瞳孔数据输入到单独的函数中,以隔离功能,并简化主线代码。

我假设存在String getSubjectCode()Pupil getPupilInformation()方法,每个方法都包含当前位于超级函数中的代码。

命名约定

次要的,但是您调用了PupilPupil的一个实例,它充其量是令人困惑的,最糟糕的是具有误导性。非静态-最终变量应始终以小写字母开头。

使用类型化集合

School.getSubjects()应该返回一个List<Subject> (或Collection)。(或者至少有一个类型正确的数组;与ObjectS无关。)

减少了条件词

中的代码数量

代码块中有很多代码循环在学校的科目上,其中大部分是在发现主题时使用的代码块。

为了理解如果没有找到主题会发生什么,我必须向下滚动到那个块的末尾,确保我正确地阅读了缩进(假设缩进是正确的),结果发现没有任何东西。

在这种情况下,不妨做一个负测试和continue,稍微“平平”循环的内脏。(代码的侧边不是一个图,它是多么令人敬畏;)

也就是说,这个功能在contains方法中是可用的--在主线代码中循环是不必要的。看下一个。

本地化功能

例如,决定一所学校是否有一门给定科目的课程应该移到School课程中:

代码语言:javascript
复制
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;
    }
}

重构的主线代码

所有这些都将主线代码转换为以下内容:

代码语言:javascript
复制
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
EN

Code Review用户

发布于 2011-11-28 17:21:26

这里有很多工作要做!我试着让你开始重构这个:

澄清了您的意图

我在这里没有看到类或方法的定义。请至少声明其中一个,以便向读者提供有关此代码试图做什么的线索。

提取类和方法名称的一种方法是检查日志记录或println。

“增加一个学生……”

啊哈!因此,您的第一步是创建一个名为“瞳孔”的类和一个方法"add“(或"addPupil")。确保方法“添加”将一个瞳孔添加到瞳孔对象的列表中。

注:如果你有一种有趣的感觉“增加一个学生到一个学生”,这看起来是多么奇怪,记下来,然后再回来,因为我们还没有完成!(也就是说,也许还有更多的抽象概念要找.)

提取类

这里的目标是创建适当的抽象。您可以使用的一个指导原则是单一责任原则,类应该有一个改变的原因。我将继续搜索您的println/注释以寻找可能的提示。

  • 我在提示符中看到“输入主题代码”。所以现在你有了一门学科课!(已经在那里了?太棒了!)
  • 向瞳孔中添加以下字段: int id、String firstName、String lastName、String address*、String* dateOfBirth。
  • 我看到了一个学校变量的运算,但是没有定义一个。也许有一个学校的目标?所以现在我们可以把学生名单移到学校去了。

*Address应该是它自己的类,其中包含street1、street2、city、state和zip的单独字段。

*最终将dateOfBirth转换为日期格式;我看到您使用的是DateTime。

将逻辑移动到类

将方法从现有条件中提取出来,并将其放在适当的类中。如果您没有适合它的类,那么创建一个新类。

例如,这个代码片段可以封装在一个方法中:

DateTime createDateOfBirth (字符串日期)

代码语言:javascript
复制
DateTime dob = DateTime.forDateOnly(Integer.parseInt(date.substring(6, 10)), 
                  Integer.parseInt(date.substring(3, 5)),
                  Integer.parseInt(date.substring(0, 2)));

小清理

进行一些小的更改,比如重命名字段、移动字段声明(限制局部变量范围),或者使用辅助函数来提高代码的可读性。

  • "String AddPupilSubj“应该是小写。可能这个生命也“太长”了。
  • 修改"if(AddPupilSubj.equals("list"))":
    1. 更改为“列表”.equals(AddPupilSubject)
    2. 添加AddPupilSubject.toLowerCase(),因为您正在将它与"list“进行比较。
    3. 还可以调用AddPupilSubject.trim()来删除任何空格,这样,如果有人输入"list ",您的函数就会工作。
票数 6
EN

Code Review用户

发布于 2011-11-18 16:07:58

在我看来,你在这里有几个需要退出的功能:

  1. findSubject
  2. 收集输入并验证
    • 我还会为更多涉及到的内容提取一个函数,比如需要验证的日期提示。

  3. 创建瞳孔并添加

其他问题:

  • 学生还能在其他地方得到输入吗?您应该避免重复此代码。
  • 为什么validDob返回一个有效的道布,而不是有两个不同版本的代码1)验证,2)转换为日期对象
票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/6139

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档