2010-11-27 92 views
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(); 

}
在示例代碼IM

試圖描述兩個單獨的實體(接口/類/無論),其在一方面應爲(我想,至少)鬆散地耦合,但另一方面確實取決於彼此並且需要彼此的某種知識。

在上面的場景中,我需要第三個類,它們實際上將它們組合到一個工作系統中。它的醜陋,因爲從現在起,上面的定義是鬆散耦合的 - student.register(c)只改變學生對象,而course.register(s)只改變課程對象。所以統一類將不得不運行s.register(c)和c.register(s)。

雖然如果我重新記錄所有的register()邏輯到一個類然後我緊緊地把它們聯繫起來。

有沒有更清晰的設計方法?

回答

4

通過使用接口,您已經在降低具體對象之間的依賴關係,這是件好事。一些依賴關係對於你的系統工作是必要的,所以你必須決定你想要容忍多少。

請考慮您的系統中的學生可以註冊課程。由於「課程」是一個界面,因此可以實施多種不同類型的課程,然後學生可以註冊其中的任何一種課程。只要學生只知道課程界面應該沒問題。對於課程而言,它只知道學生界面而不是具體的學生。

只是一件事。在你描述的雙向關聯中,我喜歡使一方成爲關係的所有者。也就是說,我可以決定學生擁有這種關係,因此,學生可以註冊課程,但課程不會註冊學生。

然後所有的客戶端代碼都會調用s.register(c)。然後,Student中的註冊表將處理關係的反面。這減少了客戶代碼瞭解雙方關係的需求。