2010-11-27 62 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中的注册表将处理关系的反面。这减少了客户代码了解双方关系的需求。