你应该在java中创建一个Generic Singleton类吗?

时间:2018-02-12 08:05:04

标签: java design-patterns singleton

我正在尝试为我的缓存创建一个CacheManager类,我要在其中注册Cache类型的对象。我的缓存可以是通用的,并接受K类型的两个密钥和V类型的值

在Stephen C评论之后编辑

** 我正在创建Cache作为内存缓存,客户端将使用它作为缓存特定对象的库。因此,一个缓存只能包含Cache<Integer, Integer>的对象,而另一个缓存可能只有Cache<String, Integer>。客户端应首先使用CacheManager注册缓存,然后才能使用它,以便CacheManager可以管理客户端的缓存并清理过期的项目等,而不是让客户端执行这些操作。 **

Cache.java

public interface Cache<K,V> {
    public V get(K key);
    public void put(K key, V value);
    public K remove(K Key);
    public void clear();
}

缓存管理器.java

public class CacheManager<K,V> {

    // Cannot make a static reference to the non-static type K,V
    private static final CacheManager<K,V> singletonInstance = new CacheManager<K,V>();
    private  Map<String, Cache<K,V>> map = new HashMap<>();

    private CacheManager() {}

    public static CacheManager<K,V> getSingletonInstance() {
        return singletonInstance;
    }


    public void addCache(Cache<K,V> cache) {
       //code goes here
    }
}

我想只创建一个CacheManager的实例,因此Singleton类的想法很明显它给出了非静态类型K,V的错误。 有没有办法做到这一点?

1 个答案:

答案 0 :(得分:1)

你问了两个不同的问题 - 第一个是&#34; 你应该创建一个通用的Singleton类......&#34;和#34;有一个很好的方法(创建一个通用的单例类)&#34;。

要回答第一个问题,我会说不,不要尝试创建泛型单例类,因为使一个单独的类失败了使用泛型的目的。

本质上,泛型允许您创建支持多种类型数据的类。但是,如果它是单例,则只打算使用该类的一个实例,因此,您应该已经知道在程序期间使用的数据类型。

您不能从静态上下文引用泛型类型参数,因为静态上下文在类的所有实例成员之间共享,其中可能包含各种不同泛型类型的类。

要回答你的第二个问题,唉,也不是,没有优雅的方式来做到这一点。通过附加的上下文,我们可能会建议一个更好的模型来用来完成你想要的东西。

更新以响应您的更新

您的CacheManager对象不应该知道它管理的缓存的通用类型,以便执行内务处理任务。可以简单地将CacheManager初始化为没有泛型类型参数的单例类,例如:

public class CacheManager {

// No generic type information should be required.
private static final CacheManager singletonInstance = new CacheManager();
// This will allow a 'Cache' of any type to be registered.
private  Map<String, Cache> map = new HashMap<>();

内务和缓存维护任务不应该关注客户端保留的数据类型,而是您可能必须创建一个额外的数据结构来支持客户端注册某些键/值的时间,并处理它们的删除。

要完成跟踪客户在Cache个对象中放置的值,您可以在Cache类中添加一个地图,将地图K映射到{{1}在那里你可以存储最后一次更新值的时间戳,然后只需要long查询缓存对象的最后更新时间戳的密钥 - 甚至可以使用条目集迭代。 / p>