当前位置:  开发笔记 > 编程语言 > 正文

大型内部类和私有变量

如何解决《大型内部类和私有变量》经验,为你挑选了1个好方法。

我遇到的一件事是服务类(比如JBoss服务)由于帮助器内部类而变得过大.我还没有找到一个打破课堂的好方法.这些助手通常是线程.这是一个例子:

/** Asset service keeps track of the metadata about assets that live on other
 * systems. Complications include the fact the assets have a lifecycle and their
 * physical representation lives on other systems that have to be polled to find
 * out if the Asset is still there. */
public class AssetService
{
  //...various private variables
  //...various methods

  public AssetService()
  {
    Job pollerJob = jobService.schedule( new AssetPoller() );
    Job lifeCycleJob = jobService.schedule( AssetLifecycleMonitor() );
  }

  class AssetPoller
  {
    public void run()
    { 
      // contact remote systems and update this service's private variables that
      // track the assets.
    }
  }

  class AssetLifecycleMonitor
  {
    public void run()
    {
      // look for assets that have meet criteria for a lifecycle shift
      // and update this service's private variables as relevant.
    }
  }
}

所以,如果我有几个帮助器并且它们都很复杂,那么整个类文件会变得非常大.我喜欢内部类,因为它表明这些类完全由服务拥有,并且仅存在于帮助该服务.我已经尝试打破这些类并将父服务作为参考传递,这主要起作用,但我不喜欢的是:

我最终暴露了包级访问器,因此分解的类可以获取变量,而在我没有公开setter之前,因为内部类具有直接访问权限.

此外,由于我不断调用访问器而不是底层变量,因此事情变得更加冗长.一个小的尼特,授予.

方便方法(例如checkAssetIsValid()或其他一些方法)现在需要包级别暴露,因此帮助程序类可以调用它们,而在内部类中它们可以是私有的.

更糟糕的是,我需要将服务实现类传递给辅助类构造函数,因为我不希望在服务实现的接口中公开这些帮助器方法,因为这会强制它们是公共的.这可能会产生一些单元测试/模拟问题.

更糟糕的是,我想要做的任何同步都会通过一些外部便捷方法(例如在轮询器更新期间的lockDownAssets())泄露出来.之前,内部类可以访问私有锁.

因此,简而言之,打破课程会失去一些我喜欢的封装.但是留下它们会导致一些大的java文件.我还没有找到解决这个问题的好方法.C++有"朋友"的概念,我很少想念,但在这种情况下实际上会有所帮助.

思考?

ddimitrov.. 7

在字节码级别,内部类只是普通的Java类.由于Java字节码验证程序不允许访问私有成员,因此它为您使用的每个私有字段生成合成访问器方法.此外,为了将内部类与其封闭实例链接,编译器将合成指针添加到外部"this".

考虑到这一点,内部类只是一层语法糖.它们很方便,你列出了一些优点,所以我列出了一些你可能想要考虑的消极方面:

您的内部类对整个父类具有隐藏的依赖性,这会对其入站接口进行模糊处理.如果将其解压缩为包私有类,则有机会改进设计并使其更易于维护.最初它更冗长,但通常你会发现:

您实际上想要共享一个值对象,而不是公开10个访问者.通常你会发现你真的不需要引用整个外部类.这也适用于IoC.

它不是提供显式锁定的方法,而是将操作与其上下文封装在一个单独的类中(或将其移动到两个类中的一个 - 外部或以前内部),这样更易​​于维护.

便捷方法属于包私有实用程序类.您可以使用Java5静态导入使它们显示为本地.

您的外部类可以绕过任何保护级别并直接访问内部类的私有成员.这本身并不坏,但它消除了表达你的设计的语言手段之一.

由于您的内部类只嵌入在一个外部类中,因此重用它的唯一方法是子类外部类.另一种方法是将显式引用传递给外部类实现的包 - 私有接口.这将允许您模拟外部并更好地测试内部类.

虽然最近的调试器非常好,但我在调试内部类之前遇到了问题(条件断点范围混乱,没有在断点处停止等)

私有类膨胀你的字节码.请参阅我的第一段 - 通常您可以使用API​​并减少合成残骸的数量.

PS我在谈论非平凡的内部类(特别是那些没有实现任何接口的内部类).三线侦听器实现很好.



1> ddimitrov..:

在字节码级别,内部类只是普通的Java类.由于Java字节码验证程序不允许访问私有成员,因此它为您使用的每个私有字段生成合成访问器方法.此外,为了将内部类与其封闭实例链接,编译器将合成指针添加到外部"this".

考虑到这一点,内部类只是一层语法糖.它们很方便,你列出了一些优点,所以我列出了一些你可能想要考虑的消极方面:

您的内部类对整个父类具有隐藏的依赖性,这会对其入站接口进行模糊处理.如果将其解压缩为包私有类,则有机会改进设计并使其更易于维护.最初它更冗长,但通常你会发现:

您实际上想要共享一个值对象,而不是公开10个访问者.通常你会发现你真的不需要引用整个外部类.这也适用于IoC.

它不是提供显式锁定的方法,而是将操作与其上下文封装在一个单独的类中(或将其移动到两个类中的一个 - 外部或以前内部),这样更易​​于维护.

便捷方法属于包私有实用程序类.您可以使用Java5静态导入使它们显示为本地.

您的外部类可以绕过任何保护级别并直接访问内部类的私有成员.这本身并不坏,但它消除了表达你的设计的语言手段之一.

由于您的内部类只嵌入在一个外部类中,因此重用它的唯一方法是子类外部类.另一种方法是将显式引用传递给外部类实现的包 - 私有接口.这将允许您模拟外部并更好地测试内部类.

虽然最近的调试器非常好,但我在调试内部类之前遇到了问题(条件断点范围混乱,没有在断点处停止等)

私有类膨胀你的字节码.请参阅我的第一段 - 通常您可以使用API​​并减少合成残骸的数量.

PS我在谈论非平凡的内部类(特别是那些没有实现任何接口的内部类).三线侦听器实现很好.

推荐阅读
重庆制造漫画社
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有