2

成績、メモ、プレゼンスなどを提供する簡単な学校用アプリケーションを作成したいと考えています。学生、教師、保護者向け。私はこの問題のためにオブジェクトを設計しようとしていますが、クラス設計の経験があまりないため、少し混乱しています。私の現在のオブジェクトのいくつかは次のとおりです。

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<>();
}

もちろんこれは一般的な考え方です。しかし、それが最善の方法ではないことは確かです。たとえば、1 人が教師であり、親 (カウンセラー) でもあり、現在のアプローチでは 2 つの 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<>();
}

誰かがこれを正しくするのを手伝ってくれるか、実用的なオブジェクトの設計を扱っている文献/記事を教えてください。

4

2 に答える 2

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;
}

教師、生徒、保護者などのいずれかになる可能性のある役割クラスは 1 つだけであることに注意してください。役割クラスは汎用であるため、教師に固有の 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 「コンボ」クラスが必要です。

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

SystemAdministrator クラスの ArrayList に入れると、リストを繰り返し処理して、学生に割り当てられているセクション (別名、学生のスケジュール) を抽出し、同様に、特定のセクションの学生を抽出できます。

ロールを除いて、User クラスには関連項目のリストがないことに注意してください。データを取得するには、グローバル (この場合は SystemAdministration) 構造にすべてのデータとアクセス機能がある限り、ログインしているユーザーとその役割に関する情報で十分です。

于 2012-12-05T15:28:12.840 に答える
1

「正しい」設計はありません。それはすべて、これらのクラス/インターフェースとの対話方法に依存します。最も自然な方法で呼び出す予定のメソッドをスケッチし、それらに基づいてクラスの適切なレイアウトを理解してください。勇気があれば、テスト駆動開発の方法論を学んでみてください。「実際の」コードの前に実際の単体テストを書くと、クラス構造を理解するのに役立ちます。

一般的な提案として、継承を避け、代わりに合成を優先してください。要素の配列を持つことRoleは、その方向への一歩です。これらのロールと対話する計画を理解し、それに応じてメソッドを追加してください。

于 2012-12-05T13:10:22.840 に答える