2010-11-27 6 views
3

イントロコード:緩く一方で(少なくとも、私はたい)でなければならない二つの別個のエンティティ(インターフェース/クラス/何でも)を記述しようとするサンプルコードのIMに疎結合例

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

}

を他方ではお互いに依存し、お互いの知識を必要とする。

上記のシナリオでは、私は実用的なシステムにそれらを実際に結合する第3のクラスが必要です。 student.register(c)は生徒オブジェクトのみを変更し、course.register(s)はコースオブジェクトのみを変更します。統合クラスはs.register(c)とc.register(s)の両方を実行する必要があります。

私はすべてのregister()ロジックを1つのクラスにリロゲートすると、それらを緊密に結合します。

これをよりクリーンな方法で設計できますか?

答えて

4

インターフェイスを使用することで、コンクリートオブジェクト間の依存度を下げることができます。それは良いことです。あなたのシステムが動作するためには、いくつかの依存関係が必要です。したがって、どれだけ許容したいのかを判断する必要があります。

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

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

すべてのクライアントコードは、s.register(c)を1回呼び出します。次に、学生の登録簿は関係の逆の面を担当します。これにより、関係の両側を知るためのクライアントコードの必要性が軽減されます。

関連する問題