【问题标题】:Should I refactor static nested classes in Java into separate classes?我应该将 Java 中的静态嵌套类重构为单独的类吗?
【发布时间】:2009-10-17 10:43:22
【问题描述】:

我继承了包含静态嵌套类的代码:

public class Foo {

// Foo fields and functions
// ...
    private static class SGroup {
        private static Map<Integer, SGroup> idMap = new HashMap<Integer, SGroup>();

        public SGroup(int id, String type) {
// ...
        }
    }
}

从阅读 SO(例如Java inner class and static nested class)我相信这相当于两个单独文件中的两个单独的类:

 public class Foo {

    // Foo fields and functions
    // ...
}

public class SGroup {
    static Map<Integer, SGroup> idMap = new HashMap<Integer, SGroup>();

    public SGroup(int id, String type) {
// ...
    }
}

如果这是正确的,维护静态嵌套类结构有什么好处,还是我应该重构?

【问题讨论】:

    标签: java class static nested


    【解决方案1】:

    这取决于类的用途。如果它与外部类耦合,例如,就像 Map.Entry 一样,只需将其留在里面。但是,如果使用没有封闭类型的类是有意义的,您不妨将其提升为顶级类。

    【讨论】:

      【解决方案2】:

      Jorn 的陈述是正确的,它通常表现为以下经验法则:

      嵌套类应该是私有的,这意味着宿主类的保持辅助逻辑仅此而已。如果您不能将它们设为私有,则可能不应该嵌套。

      例外情况是当您定义一个嵌套类以允许轻松访问托管类的状态时,在这种情况下,您应该考虑简单地合并两个类以增加内聚力。

      【讨论】:

        【解决方案3】:

        说“静态嵌套类”根本不是嵌套类并不恰当。在内部类的上下文中讨论静态嵌套类很方便,因为它们在代码中声明的方式相似,而且静态嵌套类仍然必须以封闭类作为上下文来命名。

        但是,关于静态嵌套类,有一点需要牢记:从编译器和 JVM 的角度来看,静态嵌套类是顶级类。事实上,编译器在编译时将它们逻辑地实现为顶级类(至少以前是这样;我认为现在仍然如此)。

        那么,为什么任何人都应该使用静态嵌套类呢?为什么不一直写顶级类呢?

        对我来说,静态嵌套类提供了一种方便的机制,可以在逻辑上对密切相关的类进行分组,从而使我的项目层次结构保持整洁。例如,假设我有一个包含以下表格的数据库:Clients、Encounters 和 Services。我可以使用单独的顶级类对这些表进行建模,这样可以正常工作,但是由于这些表都在同一个数据库中并且与相同的数据相关,因此我发现将它们建模为:

        class DB {
        
            static class Client {
            ...
            }
        
            static class Encounter {
            ...
            }
        
            static class Service {
            ...
            }
        
        }
        

        要使用其中一个模型的实例:

        DB.Encounter enc = new DB.Encounter();
        

        在我看来,这使代码更具可读性,因为在代码中可以立即清楚地表明,正在创建的对象源自我的数据库模型之一。它还将模型的类定义链接在一个共同的标题下,我也认为这有助于使项目更易于理解。

        但是从 JVM(和编译器,无论如何都将它们实现为顶级类[就像它在编译时也给出“匿名”内部类名称])的角度来看,这些对象是从顶级实例化的类。制作它们不依赖于任何对象的任何实例,从静态嵌套类实例化的对象也不能访问封闭类的任何私有成员。

        【讨论】:

          【解决方案4】:

          我喜欢静态内部类,因为它们提供与封闭类的松散耦合(无法访问封闭类的私有成员)静态内部类也很容易提升到顶层(因为松散耦合属性)。

          推广它们有一个简单的经验法则:
          如果另一个类(除了封闭的)需要引用 \ 使用内部类。

          【讨论】:

          • 静态内部类可以访问其封闭类的私有成员,因此不能确保失去耦合。 (当然,他们需要一个封闭类的实例来访问非静态类)。因此,您会将 java.util.Map.Entry 分解为顶级类?我不敢苟同。
          • Map.Entry 如何符合我建议的规则?它既不是静态的也不是类。虽然我同意将封闭类的引用传递给内部类绕过了松散耦合的整个想法。
          • Map.Entry 作为一个接口是隐式静态的。
          猜你喜欢
          • 2020-11-10
          • 1970-01-01
          • 1970-01-01
          • 2010-09-20
          • 2015-09-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多