【问题标题】:How do I replace this Singleton?我该如何替换这个单例?
【发布时间】:2012-04-13 03:27:47
【问题描述】:

所以我最近被添加到工作中的一个新项目中,Java 代码有大约 10-15 个 Singleton 类,它们在任何地方都在使用。这些类的目的是从服务器获取数据(当客户端应用程序启动时)并使该数据在整个程序中都可以访问,这样就不必在每次需要时都进行服务调用,这在我看来是有道理的。

但是,在阅读了很多关于单例有多糟糕的帖子后,由于紧密耦合和不可测试,我将如何替换它们?有人告诉我依赖注入,但我真的想继续将相同的数据传递给应用程序中的几乎每个对象吗?任何建议都是有用的。

【问题讨论】:

  • 我很想试一试这个问题,但它太宽泛了。标题暗示您有一个特定的单身人士 - 您能否发布一个您想要替换的具体示例,以及一些用法?

标签: design-patterns dependency-injection singleton


【解决方案1】:

我在这种情况下使用依赖注入 (DI),但正如你所说,你不喜欢它。

接下来我能想到的是 FACADE 模式,创建一个 ApplicationFacade 类并在需要的地方进行 DI。 (如果你真的不喜欢 DI,也可以将其设为静态)

【讨论】:

    【解决方案2】:

    我相信这取决于每个单身人士。例如,Singleton 可以分解成几个静态函数吗?或者它可以分解成几个更小的类。也许它只用于应用程序的一小部分;因此,重构了一个较小的类以在该模块中使用。我认为,归根结底,这取决于每个 Singleton 的使用情况。如果它使您的代码更简单、更可扩展、更简洁等,请保留它;如果没有,请重构。

    编辑:补充一下,需要重构什么?代码是否简单、干净并且有效?如果是这样,那么只需向应用程序添加功能即可。始终寻求添加代码/功能,而不是修改现有代码。最后你要回答,是否可以扩展?

    【讨论】:

    • 这些类中的大多数用于访问从服务器获取的某种数据。例如,单例 A 在初始化时进行服务调用以获取一些数据。这个类现在有 2-3 个 Collection 对象,可以在整个程序中访问(它们是不可修改的)。有一个 Singleton 是否有意义,以便程序的类可以使用这些数据来执行它的必要功能?
    【解决方案3】:

    看看Guice。您将构造函数定义为仅采用直接依赖项(没有工厂的工厂向下传递深层依赖项),用 @inject 注释每个可注入构造函数,然后创建“模块”类来定义用于任何抽象类或接口的实现在那些构造函数中使用。

    Guice 将使用反射魔法根据模块类中的指令查找实现并实例化您的对象图。它甚至足够聪明,可以自动使用无参数构造函数来处理您没有在模块中明确定义的依赖项,而无需您明确告诉它。

    您可以让 Guice 更多地融入您的架构中,但如果您只想避免一连串用于注入依赖项的工厂,那么一点 Guice 就不错了。

    【讨论】:

      【解决方案4】:

      你可以设计你的类的方式是考虑到显式的依赖关系。如果一个类使用单例:

      class Client {
        public void Method() {
          SomeService.getInstance().doSomething();
        }
      }
      

      它把依赖隐藏在里面。要将其拉出,(1)将其用于构造或(2)将其用于所涉及的方法,如果它有意义(显示选项 2):

      class Client {
        public void Method(SomeService service) {
          service.doSomething();
        }
      }
      

      这是第一步。稍后,您可以从单例中提取一个接口并使用它。这是一个缓慢的过程:重构、重新测试、迭代......

      【讨论】:

        猜你喜欢
        • 2012-07-05
        • 1970-01-01
        • 1970-01-01
        • 2019-02-05
        • 2010-12-01
        • 1970-01-01
        • 2016-07-29
        • 2021-11-15
        相关资源
        最近更新 更多