繁体   English   中英

如何重构内部类MouseAdapter?

[英]How to refactor inner class MouseAdapter?

假设我有一个像这样的文件:

import javax.swing.JPanel;
import java.awt.event.MouseAdapter;
public class Foo extends JPanel
{
    private int m;
    private int n;
    private int o;

    public Foo()
    {
        this.addMouseListener(new Bar());
    }

    class Bar extends MouseAdapter
    {
        // ...
        // methods here access and modify values of the private
        // instance variables.
        // ...
    }
}

显然,我可以向Foo添加简单的访问器和mutator,但这很快就会变得乏味并且完全破坏了封装。 我如何重构此内部类,同时将对封装的损害降到最低?

如果这些类看起来太大,则应拆分它们。 拆分它们的第一步是停止依赖外部类的私有实例变量。 如您所说,您可以添加公共获取器和设置器,但更好的方法是让Foo实现Bar的公共接口,并让Bar仅仅与该接口对话。 并用self初始化每个Bar。

public class Bar extends MouseAdapter {
    public interface Caller {
        void thingClicked();
        ...
    }
}

public class Foo extends JPanel implements Bar.Caller {
    ...
}

因此,现在在Bar中,您会遇到类似以下情况:

public void mouseUp() {
   m = m + 1;
   n = 0
}

你现在有

public void mouseUp() {
   caller.thingClicked();
}

并且,在Foo中:

public void thingClicked() {
   m = m + 1;
   n = 0
}

没有更多细节,很难弄清楚这一点,但是基本上您的外部类正在响应消息,而鼠标侦听器仅负责传递这些消息,而不负责响应这些消息。 在上面的示例中,这看起来比您已经拥有的代码更多,但是我怀疑您会发现,以这种方式对其进行切片最终会导致更少的代码-当然,这些代码更易于测试和重用。

一种方法是将类bar放在一个新文件中,然后将您需要的所有内容注入到构造函数中。 您需要将int类的原始类型更改为Integer类的对象。 然后,您可以创建一个Builder类来指导FooBar的构造。 为了简单起见,假设在所有FooBar实例中都需要相同的Baz实例:

class Builder {
  // objects that both classes need are stored as member variables
  // if you need multiple instances of baz you can also store a BazBuilder here
  private Baz baz;

  public Builder(Baz baz) {
    this.baz=baz;
  }

  public Foo buildFoo() {
    Foo foo = new Foo(baz);
    return foo;
  }

  public Bar buildBar() {
    Bar bar = new Bar(baz);
    return bar;
  }
}

这只是一个简单的示例,但很容易扩展。 Builder#buildFoo()可以接受Foo的构造函数中所需的参数, Bar也同样可以。

编辑 BazBuilder看起来像的小例子:

class BazBuilder {

 Baz build(int value) {
   return new Baz(value);
 }
}

Builder您可以像这样使用它:

class Builder {
  private BazBuilder bazBuilder;

  public Build(BazBuilder bazBuilder) {
    this.bazBuilder = bazBuilder;
  }

  public Foo buildFoo() {
    Baz baz = bazBuilder.build(5);
    Bar bar = new Bar(baz);
    Foo foo = new Foo(baz);
    foo.add(bar);
    return foo;
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM