使用泛型的工厂模式
Factory pattern using generics
我想构建一个 class 来缓存 class 使用 Map 的 CachedObject 类型。
public class CachedObject {
protected Long id;
public CachedObject(Long id) {
this.id = id;
}
}
下面是工厂class.
public class CachedObjectFactory<T extends CachedObject> {
private static Logger logger = LoggerFactory.getLogger(CachedObjectFactory.class);
private Map<Long, T> cacheMap = new HashMap<>();
public T get(Class<T> type, Long id) throws CachedObjectInstantiationException {
T cachedObject = cacheMap.get(id);
try {
if(cachedObject == null) {
cachedObject = type.getDeclaredConstructor().newInstance(id);
}
} catch(Exception e) {
throw new CachedObjectInstantiationException(e.getMessage());
}
return cachedObject;
}
}
我有一个 class 扩展 CacheableObject 如下:
@Component
class X extends CachedObject {
public X(Long id) {
super(id);
}
....
}
当我尝试使用工厂中的 get 方法创建扩展 CachedObject 的 class X 实例时,如下所示:(请注意 cachedObjectFactory 是使用 Spring 自动装配的)
@Component
class Y extends CachedObject {
CachedObjectFactory<CachedObject> cachedObjectFactory;
Y(Long id, CachedObjectFactory cachedObjectFactory) {
super(id);
this.cachedObjectFactory = cachedObjectFactory;
}
public void someMethod() {
X x = cachedFactory.get(X.class, id);
}
}
我收到编译时错误“CachedObjectFactory 类型中的方法 get(Class, Long) 不适用于参数 (Class,
Long)"。如何用工厂方法实例化一个对象X?
将一个字段声明为 CachedObjectFactory<CachedObject>
并没有任何意义——参数已经有 CachedObject
作为上限。
您可以通过将工厂更改为如下所示来编译代码:
public class CachedObjectFactory {
private Map<Long, Object> cacheMap = new HashMap<>();
public <T extends CachedObject> T get(Class<T> type, Long id) {
T cachedObject = (T)cacheMap.get(id);
try {
if(cachedObject == null) {
cachedObject = type.getDeclaredConstructor().newInstance(id);
}
} catch(Exception e) {
throw new RuntimeException(e.getMessage());
}
return cachedObject;
}
}
由于您将工厂用于许多 类,因此将其通用化并没有多大意义。
当然,如果 CachedObject
的不同子 类 的两个实例具有相同的 ID,您将获得运行时 ClassCastException
.
我想构建一个 class 来缓存 class 使用 Map 的 CachedObject 类型。
public class CachedObject {
protected Long id;
public CachedObject(Long id) {
this.id = id;
}
}
下面是工厂class.
public class CachedObjectFactory<T extends CachedObject> {
private static Logger logger = LoggerFactory.getLogger(CachedObjectFactory.class);
private Map<Long, T> cacheMap = new HashMap<>();
public T get(Class<T> type, Long id) throws CachedObjectInstantiationException {
T cachedObject = cacheMap.get(id);
try {
if(cachedObject == null) {
cachedObject = type.getDeclaredConstructor().newInstance(id);
}
} catch(Exception e) {
throw new CachedObjectInstantiationException(e.getMessage());
}
return cachedObject;
}
}
我有一个 class 扩展 CacheableObject 如下:
@Component
class X extends CachedObject {
public X(Long id) {
super(id);
}
....
}
当我尝试使用工厂中的 get 方法创建扩展 CachedObject 的 class X 实例时,如下所示:(请注意 cachedObjectFactory 是使用 Spring 自动装配的)
@Component
class Y extends CachedObject {
CachedObjectFactory<CachedObject> cachedObjectFactory;
Y(Long id, CachedObjectFactory cachedObjectFactory) {
super(id);
this.cachedObjectFactory = cachedObjectFactory;
}
public void someMethod() {
X x = cachedFactory.get(X.class, id);
}
}
我收到编译时错误“CachedObjectFactory 类型中的方法 get(Class, Long) 不适用于参数 (Class, Long)"。如何用工厂方法实例化一个对象X?
将一个字段声明为 CachedObjectFactory<CachedObject>
并没有任何意义——参数已经有 CachedObject
作为上限。
您可以通过将工厂更改为如下所示来编译代码:
public class CachedObjectFactory {
private Map<Long, Object> cacheMap = new HashMap<>();
public <T extends CachedObject> T get(Class<T> type, Long id) {
T cachedObject = (T)cacheMap.get(id);
try {
if(cachedObject == null) {
cachedObject = type.getDeclaredConstructor().newInstance(id);
}
} catch(Exception e) {
throw new RuntimeException(e.getMessage());
}
return cachedObject;
}
}
由于您将工厂用于许多 类,因此将其通用化并没有多大意义。
当然,如果 CachedObject
的不同子 类 的两个实例具有相同的 ID,您将获得运行时 ClassCastException
.