【问题标题】:Using Singleton with Interfaces Java在 Java 接口中使用单例
【发布时间】:2016-08-22 08:28:13
【问题描述】:

我想知道,如何将单例模式与接口一起使用?我已经创建了一个界面:

public interface BusinessService {

   BusinessService getInstance();

}

我做了这个实现:

public class BusinessServiceImpl implements BusinessService {

  private static BusinessServiceImpl instance = null;

  private BusinessServiceImpl(){ }

  @Override
  public BusinessServiceImpl getInstance() {
    if (instance == null) {
        BusinessServiceImpl.instance = new BusinessServiceImpl();
    }
    return BusinessServiceImpl.instance;
  }
}

如何从我的主类访问 getInstance? 我尝试了类似的东西

private BusinessService service = new BusinessServiceImpl();

(不起作用 - BusinessServiceImpl() 的构造函数是私有的)

但还有什么?你能帮帮我吗?

编辑:我正在使用 Java Spring!我不想使用 Java Springs - 依赖注入!

你好,米拉

【问题讨论】:

  • 你从那里得到了NullPointerException?堆栈跟踪在哪里?
  • 你应该使用像 Spring 或 Guice 这样的依赖注入工具。
  • 如果“BusinessSericeImpl”为单例,则不能调用“new BuisinessServiceImpl()”。你应该做 BuisinessServiceImpl.getInstance();你不能,因为 getInstance 方法不是静态的。您不能在接口中定义静态方法。你确定要单身吗?它看起来更像是工厂模式
  • 使您的 getInstance() 方法静态化。并尝试获取BusinessService service = BusinessServiceImpl.getInstance()
  • getInstance() 方法必须是静态的,因此不能是接口的一部分。否则,你需要构造一个新的实例来获取唯一的实例,这完全没有意义。为什么要首先使用单例反模式?

标签: java interface singleton


【解决方案1】:

您提供的代码有点混乱。

控制单例类的实例化的全部意义在于您必须隐藏构造函数,因此客户端无法访问它并随意创建新实例。

您的工厂方法(一种创建类实例的方法)getInstance() 是一个实例方法。您必须创建 BusinessService 的新实例才能创建 BusinessService 的实例 - 很明显这将无法正常工作。

您有几种选择来处理您的情况:

  1. 从您的接口中删除getInstance() 方法并将其作为静态方法在您的实现类中公开。您还应该将构造函数的可见性限制为private

    public class BusinessServiceImpl implements BusinessService {
    
        public static BusinessServiceImpl getInstance() {
            // instantiation logic
        }
    
        private BusinessServiceImpl() {
            // constructor logic
        }
    }
    
  2. 使用工厂类来实例化您的服务并控制实例的数量。这包括一起删除getInstance() 方法并将BusinessServiceImpl 类的可见性限制为package

    class BusinessServiceImpl implements BusinessService {
    
        BusinessServiceImpl() {
            // constructor logic
        }
    }
    
    // should be in the same package as BusinessServiceImpl
    public final class BusinessServiceFactory {
    
        private BusinessServiceImpl instance;
    
        public BusinessService getInstance() {
            // instance creation logic, same as singleton creation logic
        }
    
    }
    
  3. 使用枚举来处理单例逻辑。从您的界面中删除 getInstance() 方法。

    public enum BusinessServiceImpl implements BusinessService {
    
        INSTANCE;
    
        // implement the methods from your interface
    }
    

【讨论】:

  • 不错的答案。选项 1. 将是标准选项,只有您可能更喜欢问题中的 getInstance() 返回 BusinessService。我会考虑 2. 要求过于复杂,并将其保留用于更复杂的情况。数字 3. 很优雅,虽然不是标准的enumuse。
  • 好的,谢谢。可能我在获得单例模式工作时遇到问题,因为我试图将它参与到 Java Spring 中。当我使用注释时,它运行良好。但我想让它工作,没有注释。
  • 所有提供的示例都没有使用任何与 Spring 相关的注释。它只是普通的 Java 代码。分析您的需求,了解解决方案的复杂性并尝试其中一种。
猜你喜欢
  • 1970-01-01
  • 2013-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-18
相关资源
最近更新 更多