单例模式,配置和依赖注入

时间:2016-06-20 17:40:55

标签: java singleton

我目前正在将一个C库移植到Java。 C库连接到外部设备,并提供配置设备和接收数据的功能。我设计的核心是一个Connection类,它封装了与设备的连接,并提供了使用JNA生成的低级C API映射。

由于大多数C库没有很好地转换为OO-World of Java(包含100多个函数的单头库),因此我有一些“Manager”类可以访问大多数功能。< / p>

创建多个这些类没有意义,因为C库只管理一切资源(配置,数据缓冲区等)。所以我想为我的Java类实现Singleton模式(实际上也向我的新java库的用户发出信号,整个系统中只有一个Manager对象)。

此外,我希望能够使用外部配置文件配置这些Manager类。我之前从未实现过配置实用程序,所以我真的不知道放在哪里。

最后,我的所有Manager类都需要引用Connection对象。

所以我需要一个允许我的设计:

  1. 使我的Java类独一无二(Singleton Pattern)
  2. 注入我的Connection对象
  3. 使用配置文件配置我的类
  4. 有什么想法吗?

2 个答案:

答案 0 :(得分:1)

对于前两点,这样的事情可以解决问题:

public class Connection{

    private static Connection instance = null;
    private String connectionString;

    protected Connection() {
    }

    public static Connection getInstance() {
       if(instance == null) {
          instance = new Connection();
       }
       return instance;
    }

    public void setConnectionString(String connectionString){
        this.connectionString = connectionString;
    }

    public String getConnectionString(){
        return this.connectionString;
    }
}

这是java中单例的典型示例。构造函数为protected,因此您无法使用new关键字对其进行实例化。相反,你这样使用它:

Connection con = Connection.getInstance();

getInstance()负责实例化,并确保只存在一个单例实例。例如,这个:

    Connection con = Connection.getInstance();
    con.setConnectionString("foobar");

    Connection con2 = Connection.getInstance();
    System.out.println(con2.getConnectionString());

将打印foobar

对于第三点,我会将你推荐给已经得到答复的this question

答案 1 :(得分:1)

public static Connection getInstance() {
       if(instance == null) {
          instance = new Connection();
       }
       return instance;
}

此实现违反了单例原则。考虑使用两种惰性初始化方法之一:

  1. 带有同步关键字 public synchronized static Connection getInstance() { ... }

  2. 按需初始化持有人惯用语。

    public final class Connection {
    
        private static class Holder {
            private static final Connection INSTANCE = new Connection();
        }
    
        private Connection() {}
        public static Connection getInstance() { 
            return Holder.INSTANCE;
        }
    }
    

为此,按需初始化持有人惯用语是一个懒惰的同步Singleton,并且比具有同步关键字的第一个解决方案性能更高。