提高课堂的凝聚力和耦合能力

时间:2011-06-16 18:17:57

标签: java oop loose-coupling cohesion

我得到了这组代码,需要提出改进代码的内聚和耦合的方法。但我认为这些类很好地解耦,因为看起来它们正在利用事件。在凝聚力方面,所有的init()调用都放在一起,对我来说一切似乎都很好。

public class A
{
    private C t;
    private B g;
    public static void main(String args[]) {
        // Creates t and g.
        t = new C();
        t.init();
        g = new B();
        g.init();
        g.start(this);
    }
    pubic void update (Event e)
    {
        // Performs updating of t based on event
    }
}

public class C
{
    public C() { ... }
    public void init() { ... }
}

public class B
{
    public B() { ... }

    public void init() { ... }

    public void start(A s) {
        e = getNextEvent();
        while (e. type != Quit)
            if (e.type == updateB)
                update(e) ;
            else
                s.update(e) ;
        e = getNextEvent();
    }

    public void update(Event e) { ... }
    }
}

还有办法改善班级凝聚力和耦合吗?它看起来不错,但我想我错过了一些东西。

感谢您提出任何建议。

4 个答案:

答案 0 :(得分:1)

开始编写单元测试(更好的是,做TDD)。联合(以及在较小程度上,内聚力或缺乏)将立即变得明显。

例如,类B的start方法有一个类型为A的参数。在你的例子中你可以实例化A,但是如果A有其他依赖项怎么办?也许所有启动需求都是A实现的接口(使用更新方法)。

getNextEvent做了什么?如果它使用其他依赖项,那么在测试工具中获取B可能会很困难。

测试有助于验证您的设计。

答案 1 :(得分:0)

如果没有看到更多代码,很难说代码是如何分离的。事件是解耦代码的一种方法,但也可能使代码更难以理解和调试。

在设计类时,高内聚意味着许多方法相互重用,而低耦合意味着您只需要暴露一些公共方法。

在设计包时,高内聚意味着包中的许多类相互依赖,而低耦合意味着只有少数是公共范围,或者通过接口与其他类的消息。

高凝聚力,低耦合性的好处应该是减少痛苦,特别是在应对变化时。如果它不能减轻疼痛,不要花很多时间来优化它。我知道这听起来好像我在这里发表陈词滥调,但在衡量高凝聚力,低耦合度是否“足够好”时,你应该记住自己的指标,而不是依赖于那些不一定了解的人的意见。你试图解决的问题。

答案 2 :(得分:0)

如果原始设计将来要包含其他功能或类,正如您所说,使用事件处理程序,它已被使用,然后只关注实现的策略模式和类或接口上的优化。

答案 3 :(得分:0)

一个建议是将事件处理逻辑与控制器逻辑(A类)分离。

所以你有4种类型:

  • 用于运行“服务器”(A)的主类
  • 线索侦听事件(B)
  • 将更新的模型层(C)
  • 一个事件处理程序类,它将支持对事件(D)的某些操作

看起来像这样:

public class Main {
  private Model m;
  private EventListener listener;

  ... main() {
    m = new Model();
    listener = new EventListener();

    EventHandler eventHandler = new MyEventHandler();

    // set the event handler
    listener.setEventHandler(eventHandler);

    listener.start(m);
}

public class Model {
  // nothing to see here
}

public class EventListener() {

  private EventHandler handler = new DefaultEventHandler();

  public void start(final Model m) {
    // startup
    while (event.type != Event.Quit) {
      // get event
      handler.handleEvent(event, m);
    }
    // shutdown
  }

  public void setEventHandler(EventHandler eh) { this.handler = eh }
}

public class MyEventHandler implements EventHandler {

  public void handleEvent(Event e, Model m) {
    // update the model
  }

}

请注意,在这个新设计中,更新模型的业务逻辑(在您的示例中为C)已移至外部类而不是“Runner”类。这有点干净,因为Main类不需要知道什么是事件以及如何处理它们。

另一个优点是使用它可以使用链式事件处理程序或多个串行事件处理程序轻松编写复杂事件处理代码。实现异步事件处理也非常简单,因为B只负责调用处理程序而不需要了解事件类型。这有时被称为Publish/Subscribe,并使监听器(B)和处理程序(您的更新(e)方法)松散耦合