イントロコード:
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つのクラスに再ログインすると、それらを緊密に結合します。
これを設計するためのよりクリーンな方法はありますか?