【问题标题】:To class variable or not to class variable?分类变量还是不分类变量?
【发布时间】:2012-07-25 19:35:41
【问题描述】:

我有一个类Foo 有一个方法doSomething,它使用两个与类相关的变量bc,这些变量的获取/创建成本很高。我的第一个版本如下所示:

public class Foo {

    private final A a;

    public Foo(A a) {
        this.a = a;
    }

    public void doSomething() {
        final B b = a.getB();
        final C c = b.getC();

        for (int i = 0; i < 1000; i++) {
            // do something with b and c
        }
    }
}

所以我通过类变量a 获得第一个对象(B 类型),通过第一个对象获得第二个对象(C 类型)。

现在,由于这些变量与类相关,并且该方法总是只被调用一次(尽管不一定在创建Foo 类型的对象时),所以我考虑将它们设为类变量也是如此:

public class Foo {

    private final A a;
    private final B b;
    private final C c;

    public Foo(A a) {
        this.a = a;
        b = a.getB();
        c = b.getC();
    }

    public void doSomething() {
        for (int i = 0; i < 1000; i++) {
            // do something with b and c
        }
    }
}

如果这两个版本中的任何一个,我不确定要使用哪个版本。因为可以从现有的类变量a 中检索它们,所以我不知何故让这两个变量成为类成员感到不舒服。但是,它会增加 IMO 方法的可读性。

【问题讨论】:

    标签: java class-variables


    【解决方案1】:

    你完全正确。如果它增加了可读性,那么一定要这样做。但是,我会问你:在课堂上引用 A 的目的是什么?只是为了获得B和C吗? 在这种情况下,我只需在 Foo 的构造函数中输入 B 和 C!

    通过这种方式,您甚至可以通过打破对 A 的依赖来使其更具可读性 并且 使对 B 和 C 的依赖更加明确。

    另外,请考虑您是否在类的其他方法中使用这些变量。如果答案是肯定的——这表明它们应该是类成员,但是,如果类包含许多使用这些变量的方法,则可能表明相反。

    这里应该遵循的一般原则是High Cohesion的原则

    【讨论】:

    • 我把sn-p弄得太简单了→不幸的是我没有办法摆脱类变量a,但是类中确实只有这个方法,所以基本上all 方法正在使用这些变量。 :P
    • 在这种情况下,我会问自己,为什么这段代码首先被隔离到一个单独的类中?难道它可以简单地是一个类中的一个方法,它实际上使用了这个逻辑?
    • 它不是另一个类中的方法有两个原因:1. 与类似的方法一起它会使该类变得混乱(阅读:doSomething 对于它自己的类来说足够大),2.它是从抽象层调用的 - 所以我实际上想隐藏实现。从两个赞成的答案中,我得出结论:使用局部变量作为类成员,但前提是它们与类密切相关并且它们显着提高了可读性。那么又是没有务实答案的问题之一? :-)
    • @htorque 为什么这是您的务实答案 :-) 这是处理没有黑色或白色答案的灰色和模糊区域的问题之一,只是经验法则和指导方针不同的人解释不同..
    【解决方案2】:

    一般来说,如果可以使用局部变量,则最好使用字段。

    使用局部变量

    • 将变量限制在其使用位置。
    • 使用更少的内存。
    • 是线程安全的。

    【讨论】:

      【解决方案3】:

      为什么不在你的类 Foo 中存储 B 和 C 的实例?你在课堂上的某个地方引用 A 吗?否则,将 B 和 C 都存储为实例变量不会降低内存效率,因为存储一个 A 对象包含一个 B 和 C 对象。

      【讨论】:

        【解决方案4】:

        根据我的经验,静态(或类变量|字段|方法)通常会在一段时间后变得邪恶,需要重构,除非这些东西本质上是静态的(例如 Math.PI 或 Math.max()或诸如此类的静态事物)。如果这些方法基于任何动态进行一些计算,我会将它们作为实例。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-07-14
          • 2021-06-29
          • 2016-03-03
          • 2022-01-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多