我想创建简单的学校应用程序,提供成绩,笔记,存在等。适用于学生,老师和家长。我正在尝试为这个问题设计对象,我有点困惑 - 因为我在课堂设计方面不是很有经验。我目前的一些目标是:
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<>();
}
如果有人能帮助我做到这一点,或者只是指出一些涉及实际物体设计的文献/文章,请。
答案 0 :(得分:2)
在这样的系统中,您似乎可以创建一个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. }
}
然后你有了你的Role对象:
public class Role
{
private String name;
private String description;
}
请注意,只有一个角色类可以是教师,学生,家长等。由于Role类是通用的,我们没有其中的函数,例如addGrade(),因为它特定于教师。
当用户使用适当的凭据登录时,此类系统已经知道与用户关联的角色。通常,特定于角色的选项卡,链接和其他UI元素将根据角色显示(或不显示)。您可以在此处查看登录的用户是否处于特定角色(user.hasRole(...))。对于其可见性由角色确定的每个UI元素,您必须具有if(user.hasRole(...))。
关于构图问题,该系统严重依赖于对象之间的关系。让我们考虑学生和辅导员之间的关系 - 辅导员有学生分配给他/她。同样,任何给定的学生都有很多辅导员。你有很多关系,需要一个能够跟踪独特的学生辅导员组合的结构:
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.
}
}
您可以为其他关系做同样的事情 - 父母 - 学生,教师 - 部门等.SystemAdministration类不是角色,而是负责向您提供所有数据的实体。
作为建议,请考虑Section对象:
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“combo”课程:
public class StudentSection
{
public Section section;
public User student;
}
当放入SystemAdministrator类的ArrayList时,现在您可以遍历列表以提取分配给学生的部分(也就是学生的日程安排),同样地,他们是给定部分的学生。< / p>
请注意,除了角色之外,我们没有User类中的相关项列表。要获取任何数据,只要您拥有全局(在本例中为系统管理)结构中的所有数据和访问功能,有关已登录用户及其角色的信息就足够了。
答案 1 :(得分:1)
没有“正确”的设计;这一切都取决于您计划如何与这些类/接口进行交互。尝试以最自然的方式绘制您打算调用的方法,并从这些方法开始,以了解您的类的良好布局。如果您感到勇敢,请尝试学习测试驱动开发方法;在“真实”代码之前编写实际的单元测试可以帮助你理解课堂结构。
作为一般建议,尽量避免继承,而不是赞成组合。拥有一系列Role
元素是向这个方向迈出的一步;尝试了解您计划与这些角色进行交互,并相应地添加方法。