简体   繁体   English

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

[英]Singleton Pattern, Configuration and Dependency Injection

I am currently porting a C library to Java. 我目前正在将C库移植到Java。 The C library connects to an external device and provides functions to configure the device and receive data. C库连接到外部设备,并提供配置设备和接收数据的功能。 The core of my design is a Connection class that encapsulates the connection to the device and provides the low-level C API mapping generated using JNA. 我设计的核心是一个Connection类,该类封装到设备的连接并提供使用JNA生成的低级C API映射。

Since most of the C library doesn't translate that well into the OO-World of Java (Single header library containing 100+ functions) i have a couple of "Manager" classes that provide access to most of the functionality. 由于大多数C库不能很好地将其转换为Java的OO-World(包含100多个函数的单个标头库),所以我有几个“ Manager”类可提供对大多数功能的访问。

Creating more than one of these classes doesn't make sense, since the C library only manages one resource of everything (configuration, data-buffer, etc). 创建多个此类都不是没有道理的,因为C库仅管理所有资源的一种(配置,数据缓冲区等)。 So i want to implement the Singleton pattern for my Java classes (effectively also signaling the users of my new java library, that there is only ONE Manager object in the whole system). 所以我想为我的Java类实现Singleton模式(有效地还向新Java库的用户发出信号,即整个系统中只有一个Manager Manager对象)。

Additionally i want to be able to configure these Manager classes using an external config file. 另外,我希望能够使用外部配置文件配置这些Manager类。 I have never implemented a configuration utility before, so i don't really know where to put that. 我以前从未实现过配置实用程序,所以我真的不知道该放在哪里。

Lastly ALL of my Manager classes need a reference to a Connection object. 最后,我所有的Manager类都需要对Connection对象的引用。

So i need a design that allows me to: 所以我需要一个允许我执行以下操作的设计:

  1. Make my Java classes unique (Singleton Pattern) 使我的Java类具有唯一性(Singleton模式)
  2. Inject my Connection object 注入我的Connection对象
  3. Configure my classes using a config file 使用配置文件配置我的班级

Any ideas? 有任何想法吗?

For the first two points, something like this would do the trick : 对于前两点,这样的方法可以解决问题:

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;
    }
}

It's a classic example of a singleton in java. 这是Java中单例的经典示例。 The constructor is protected , so you can't use the new keyword to instantiate it. 构造函数protected ,因此您不能使用new关键字实例化它。 Instead, you use it like this : 相反,您可以这样使用它:

Connection con = Connection.getInstance();

getInstance() takes care of the instantiation and ensures only one instance of your singleton will ever exist. getInstance()负责实例化,并确保单例仅存在一个实例。 For instance, this : 例如,这:

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

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

will print foobar 将打印foobar

For the third point, I would refer you to this question where it has already been answered. 对于第三点,我想请您看看这个问题,它已经有了答案。

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

This implementation violates the singleton principle. 此实现违反了单例原则。 Consider to use one of both lazy initialization methods: 考虑使用两种惰性初始化方法之一:

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

  2. init-on-demand holder idiom. 按需初始化持有人惯用法。

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

To that, the init on demand holder idiom is a lazy synchronized Singleton and more performant than the first solution with the synchronized key word. 为此,按需初始化持有者惯用语是一个惰性同步Singleton,并且比具有同步关键字的第一个解决方案性能更高。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM