3

イントロコード:

public interface Course {

    /**
     * returns the number of units (hours) a specific course is
     */
    public int units();

    /**
     * returns the number of students signed up for the course
     */
    public int numOfStudents();

    /**
     * returns the maximum number of students the course can have signed up to it
     */
    public int maxNumStudents();

    /**
     * returns whether or not the student is enrolled in the course
     */
    public boolean registered(Student s);

    /**
     * enrolls s in the course
     * 
     * @pre     this.registered(s) == false
     * @pre     this.numOfStudents() < this.maxNumStudents()
     * 
     * @post    this.registered(s) == true
     * @post    this.numOfStudents() == $prev(this.numOfStudents()) + 1
     */
    public void register(Student s);

}


public interface Student {

    /**
     * enrolls the student in course c
     * 
     * @pre     c.registered(this) == false
     * @pre     c.numOfStudents() < c.maxNumStudents()
     * @pre     this.totalUnits() + c.units() <= 10
     * 
     * @post    c.registered(s) == true
     * @post    this.totalUnits() == $prev(this.totalUnits()) + c.units()
     */
    public void register(Course c);

    /**
     * return the total number of units this student currently is enrolled in
     * 
     * @pre     true
     * @post    0 <= $ret <= 10
     */
    public int totalUnits();

}

サンプルコードでは、2つの別々のエンティティ(インターフェイス/クラス/その他)を記述しようとしています。これらのエンティティは、一方では(少なくとも)緩く結合されている必要がありますが、他方では相互に依存しており、特定の知識が必要です。お互いの。

上記のシナリオでは、実際にそれらを動作するシステムに統合する3番目のクラスが必要になります。今のところ、上記の定義は可能な限り緩く結合されているため、醜いです。student.register(c)はstudentオブジェクトのみを変更し、course.register(s)はコースオブジェクトのみを変更します。したがって、統合クラスはs.register(c)とc.register(s)の両方を実行する必要があります。

ただし、すべてのregister()ロジックを1つのクラスに再ログインすると、それらを緊密に結合します。

これを設計するためのよりクリーンな方法はありますか?

4

1 に答える 1

4

インターフェイスを使用することで、具象オブジェクト間の依存関係のレベルがすでに低下しているので、それは良いことです。システムが機能するにはある程度の依存関係が必要なので、許容する量を決定する必要があります。

システム内の学生がコースに登録できることを考慮してください。コースはインターフェースであるため、さまざまな種類のコースを実装できる可能性があり、学生はそれらのいずれかに登録できるようになります。学生がコースのインターフェースだけを知っている限り、それは問題ないはずです。コースについても同じことが言えますが、具体的な学生ではなく、学生のインターフェースしか知りません。

たったひとつ。あなたが説明するようにあなたが双方向の関係を持っている状況では、私は一方の側を関係の所有者にするのが好きです。つまり、学生が関係を所有していると判断できるため、学生はコースに登録できますが、コースは学生を登録しません。

次に、すべてのクライアントコードがs.register(c)を1回呼び出します。その後、Studentのレジスターは、関係の逆側を処理します。これにより、関係の両側を知るためのクライアントコードの必要性が減ります。

于 2010-11-27T12:42:17.960 に答える