【问题标题】:Improving Cohesion and Coupling of Classes提高类的凝聚力和耦合度
【发布时间】:2011-06-16 18:17:56
【问题描述】:

我得到了这组代码,需要提出改进代码内聚和类耦合的方法。但我认为这些类很好地解耦,因为看起来它们正在使用事件。在凝聚力方面,所有的 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) { ... }
    }
}

还有什么方法可以提高类的凝聚力和耦合度吗?对我来说看起来不错,但我认为我遗漏了一些东西。

感谢您对此提出任何建议。

【问题讨论】:

  • A、B 和 C 之间应该有什么关系?你能改变你的例子来有有意义的课程吗? this 不能从静态上下文访问,顺便说一句。

标签: java oop loose-coupling cohesion


【解决方案1】:

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

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

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

测试可以帮助验证您的设计。

【讨论】:

    【解决方案2】:

    一个建议是将事件处理逻辑与控制器逻辑(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) 和处理程序(您的 update(e) 方法)松散耦合

    【讨论】:

      【解决方案3】:

      如果没有看到更多代码,很难说您的代码是如何解耦的。事件是解耦代码的一种方式,但也会使代码更难理解和调试。

      在设计类时,高内聚意味着许多方法可以相互重用,而低耦合意味着您只需要公开几个公共方法。

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

      高内聚、低耦合的好处应该是减少痛苦,尤其是在应对变化时。如果它不能减轻痛苦,就不要花很多时间优化它。我知道这听起来像是在说陈词滥调,但是在衡量高内聚、低耦合是否“足够好”时,您应该牢记自己的指标,而不是依赖不一定了解您正在尝试解决的问题。

      【讨论】:

        【解决方案4】:

        如果最初的设计是将来合并另一个功能或类,使用事件处理程序,如您所说,它已被使用,那么只需专注于实现的策略模式和类或接口的优化。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-02-04
          • 2011-07-14
          • 1970-01-01
          • 2019-02-14
          • 2016-07-17
          相关资源
          最近更新 更多