如何为简单的学校应用程序设计对象



我想创建一个简单的学校应用程序,提供成绩、笔记、状态等。为学生、老师和家长。我正试图为这个问题设计对象,但我有点困惑——因为我在课堂设计方面没有太多经验。我现在的一些目标是:

class PersonalData() {
private String name;
private String surename;
private Calendar dateOfBirth;
[...]
}
class Person {
private PersonalData personalData;
}
class User extends Person {
private String login;
private char[] password;
}
class Student extends Person {
private ArrayList<Counselor> counselors = new ArrayList<>();
}
class Counselor extends Person {
private ArrayList<Student> children = new ArrayList<>();
}
class Teacher extends Person {
private ArrayList<ChoolClass> schoolClasses = new ArrayList<>();
private ArrayList<Subject> subjects = new ArrayList<>();
}

这当然是一个普遍的想法。但我确信这不是最好的方式。例如,我希望一个人既可以是老师,也可以是家长(辅导员),而现在的方法使我有两个person对象。我希望该用户在成功登录后获得它所拥有的所有角色(学生或教师或(教师和家长))。我认为我应该制作和使用一些接口,但我不确定如何正确地做到这一点。可能是这样的:

interface Role {
}
interface TeacherRole implements Role {
void addGrade( Student student, Grade grade, [...] );
}
class Teacher implements TeacherRole {
private Person person;
[...]
}
class User extends Person{
ArrayList<Role> roles = new ArrayList<>();
}

如果有人能帮我纠正这一点,或者给我指一些涵盖实用对象设计的文献/文章,请帮忙。

在这样的系统中,似乎可以创建一个包含所有个人属性和帐户信息的User类:

public class User
{
// personal properties
private String name;
private String surname;
private Calendar dateOfBirth;
// account properties;
private String login;
private String password; // note that string may be more convenient than char[]
// role properties
public ArrayList<Role> roles;
...
public bool hasRole(Role role) // or isInRole(Role role)
{ // implementation here. }
}

然后你就有了你的角色对象:

public class Role
{
private String name;
private String description;
}

请注意,只有一个角色类可以是教师、学生、家长等。由于角色类是通用的,我们在其中没有addGrade()等函数,因为它是特定于教师的。

当用户使用正确的凭据登录时,这样的系统将已经知道与该用户相关联的角色。通常,角色特定的选项卡、链接和其他UI元素会根据角色显示(或不显示)。这是您检查登录用户是否处于特定角色(user.hasRole(…))的地方。对于可见性由角色决定的每个UI元素,您必须具有if(user.hasaRole(..))。

就组成问题而言,这个系统是一个严重依赖于对象之间关系的系统。让我们来考虑一下学生和辅导员之间的关系——辅导员把学生分配给他/她。同样,任何一个学生都有很多辅导员。你有一种多种关系,需要一种结构来跟踪独特的学生-辅导员配对的组合:

public class StudentCounselor
{
public User student;
public User counselor;
}

谁来记录这一切?很可能是系统本身,而不是其他用户。

public class SystemAdministration
{
public static ArrayList<StudentCounselor> studentCounselors = new ArrayList<StudentCounselor>();
public static void addStudentCounselor(User student, User counselor)
{
//  Check to see first that the student-counselor combo doesn't exist
studentCounselors.addItem(student, counselor);
// addItem may not be the precise name of the function in ArrayList.
}
// function to obtain all students of a counselor
public static ArrayList<User> getStudentsOfCounselor(User counselor)
{
// iterate through the studentCounselors ArrayList and pick only
// the Student-Counselor whose counselor is the same counselor
// as the one passed into this function.
// Then extract the student property out of the fitting 
// Student-Counselor.
// Return the list of students. 
}
public static ArrayList<User> getCounselorsOfStudent(User student)
{
// Similar as above, but the other way around.
}
}

你可以对你的其他关系做类似的事情——家长-学生、教师部分等。系统管理类不是一个角色,而是负责为你提供所有数据的实体。

作为一项建议,考虑本节的目标:

public class Section
{
public User teacher; // who teaches it
public Course course; // what is the subject, because > 1 teacher might teach the same one.
public TimeBlock timeBlock; // when is this section administered?
public Venue venue; // what room or what facility
}

您必须创建TimeBlock和Venue类。当这个结构放在ArrayList中时,它将能够回答以下问题:"作为一名教师,我将教授哪些部分?"这回答了"我将教授什么科目、何时何地?">

至于学生,你需要StudentSection"组合"课程:

public class StudentSection
{
public Section section;
public User student;
}

当放入SystemAdministrator类的ArrayList中时,现在您可以遍历该列表来提取分配给学生的部分(也称为学生的时间表),以及指定部分的学生。

请注意,在User类中,除了角色之外,我们没有相关项目的列表。要获取任何数据,只要您在全局(本例中为SystemAdministration)结构中拥有所有数据和访问功能,有关登录用户及其角色的信息就足够了。

没有"正确"的设计;这完全取决于您计划如何与这些类/接口交互。试着以最自然的方式勾勒出你打算调用的方法,并从中了解什么是适合你的类的好布局。如果你觉得勇敢,试着学习测试驱动开发方法;在编写"真正的"代码之前编写实际的单元测试可以帮助您确定类结构。

作为一个普遍的建议,尽量避免继承,而倾向于组合。具有CCD_ 1元素的阵列是朝着该方向迈出的一步;试着理解您计划与这些角色进行交互,并相应地添加方法。

最新更新