Java 帮助创建泛型类以避免代码重复
我有一个简单的问题,使用Appengine保持干燥 除作为参数发送的对象外,以下两个功能完全相同。实际上,我有15个这样的函数。我试图找到一种方法来创建一个超级类或泛型来实现这一点Java 帮助创建泛型类以避免代码重复,java,generics,google-app-engine,dry,Java,Generics,Google App Engine,Dry,我有一个简单的问题,使用Appengine保持干燥 除作为参数发送的对象外,以下两个功能完全相同。实际上,我有15个这样的函数。我试图找到一种方法来创建一个超级类或泛型来实现这一点 public void deleteRecord(Person s) { PersistenceManager pm = PMF.get().getPersistenceManager(); try { Person p = pm.getObjectById(Person.class
public void deleteRecord(Person s) {
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
Person p = pm.getObjectById(Person.class, s.getId());
pm.deletePersistent(p);
} finally {
pm.close();
}
}
及
不幸的是,我似乎不能使用泛型,因为泛型不支持t.class
有什么好的建议怎么做不带复印机
多谢各位。
Daniel这不需要泛型;使用thing.getClass() (您应该在那里添加一个null检查,以防传入的参数为null)
[注意:在我发布答案后,当我意识到这里不需要泛型时,我更改了答案…]最简单的方法是将类型作为参数引入:
public <T> void deleteRecord(Class<T> type, T s) {
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
T p = pm.getObjectById(type, s.getId());
pm.deletePersistent(p);
} finally {
pm.close();
}
}
public void deleteRecord(类类型,ts){
PersistenceManager pm=PMF.get().getPersistenceManager();
试一试{
tp=pm.getObjectById(类型,s.getId());
pm.1(p);
}最后{
pm.close();
}
}
如果您的人员、产品等只是简单的类,没有子类,那么您可以使用
getClass()
而不是像Scott建议的那样指定显式参数。如果您在DAO中使用此参数,我倾向于用类初始化它。所以也许
public class DAO<T> {
private Class klass
public DAO(Class klass) {
this.klass = klass;
}
public void deleteRecord(T record) {
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
T p = pm.getObjectById(this.klass, record.getId());
pm.deletePersistent(p);
} finally {
pm.close();
}
}
}
公共类DAO{
二等舱
公共DAO(klass类){
this.klass=klass;
}
公共记录(T记录){
PersistenceManager pm=PMF.get().getPersistenceManager();
试试{
tp=pm.getObjectById(this.klass,record.getId());
pm.1(p);
}最后{
pm.close();
}
}
}
这可能不是最简单的做事方式,但我忍不住认为从长远来看这是最有意义的
创建一个接口
// This is a terrible name, I know
public interface Identifier {
// Assumes ID was an int
public int getId();
// Maybe have setId, too
}
在每个类中,实现接口及其方法
public class Person implements Identifier {
public int getId() {
//Implementation details here
}
}
最后,您的删除方法:
public void deleteRecord(Identifier s) {
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
Identifier p = pm.getObjectById(s.getClass(), s.getId());
pm.deletePersistent(p);
} finally {
pm.close();
}
}
注意:我还没有完全测试这个。。。具体地说,我还没有测试pm.deletePersistent(p)是否可以使用。DRY是一个很好的原则。吻也是如此;-) 这将被称为,例如:
theObject.deleteRecord(Person.class, s.getId());
theObject.deleteRecord(Product.class, s.getId());
由于这是一个无效的方法,而且PersistenceManager似乎无法处理泛型类型,因此我建议避免使用泛型。如果适用,此方法还有一个额外的好处,即您不需要修改产品、人员等的类型层次结构
缺点是,如果从多个地方调用此方法,可能会有许多地方更改签名-但很容易让编译器知道需要多长时间。您可以使用枚举来隐藏这一点:
class FetchableThing {}
class Person extends FetchableThing {}
class Organisation extends FetchableThing {}
enum DAO<T extends fetchableThing> {
Person(Person.class), Organisation(Organisation.class);
private Class<T> myClass;
private DAO(Class<T> myClass) { this.myClass=myClass;}
public delete(String id) {
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
T p = (T) pm.getObjectById(myClass, id);
pm.deletePersistent(p);
} finally {
pm.close();
}
}
}
DAO.Person.delete("1234");
DAO.Organsation.delete("1234");
class-FetchableThing{}
类Person扩展了FetchableThing{}
类组织扩展了FetchableThing{}
枚举道{
人(人.类)、组织(组织.类);
私有类myClass;
私有DAO(类myClass){this.myClass=myClass;}
公共删除(字符串id){
PersistenceManager pm=PMF.get().getPersistenceManager();
试一试{
tp=(T)pm.getObjectById(myClass,id);
pm.1(p);
}最后{
pm.close();
}
}
}
DAO.Person.delete(“1234”);
DAO.组织。删除(“1234”);
你不能修改你的方法来接受一个类而不是一个对象吗?这些方法需要在同一个类中,还是每个方法都像它自己的一个类中一样?除了object之外,它不提供getId方法,所以你需要声明一个东西,因为你需要一个具有getId()方法的公共超类(或接口)。或者传递s.getId的结果()将其作为参数引入方法中?thing的运行时类是否保证是持久性管理器所期望的类?它难道不是它的子类吗?例如,如果使用Hibernate持久化,则thing可能是一个延迟加载代理,它只实现持久性管理器所期望的类。我正在编写sa我的东西。@pstanton:实际上我是在看到Buhb的回复之前写的。但是,结果证明Grundlefleck可能有更好的主意。不,我个人更喜欢你/我们的方法。编译时安全性和继承的正确使用=好。你的意思是在你的示例中使用Product.class
?你不是指参数type
而不是?我想你不是想写Product.class
而是想写type
…对吗?你能不能用另一个方法来包装这个方法,这个方法只需要一个s
参数?前提是type参数等于s
的确切类。但是如果是这样的话,你根本不需要泛型类型唯一的问题是,您的代码并没有在编译时限制试图删除无效类型的人,例如object.deleteRecord(Integer.class,s.getId())将编译,但在运行时失败。即使这样,我可能也不会转向泛型,我最有可能使用枚举类型提供的编译时约束。因此,枚举将包含可以提供所需15个左右类的成员。您认为泛型比这更好吗?“PersistenceManager似乎不适用于泛型类型”我认为Apache(或Oracle)的任何代码都不会使用泛型。
public void deleteRecord(Class classOfProduct, Object id) {
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
Object p = pm.getObjectById(classOfProduct, id);
pm.deletePersistent(p);
} finally {
pm.close();
}
}
theObject.deleteRecord(Person.class, s.getId());
theObject.deleteRecord(Product.class, s.getId());
class FetchableThing {}
class Person extends FetchableThing {}
class Organisation extends FetchableThing {}
enum DAO<T extends fetchableThing> {
Person(Person.class), Organisation(Organisation.class);
private Class<T> myClass;
private DAO(Class<T> myClass) { this.myClass=myClass;}
public delete(String id) {
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
T p = (T) pm.getObjectById(myClass, id);
pm.deletePersistent(p);
} finally {
pm.close();
}
}
}
DAO.Person.delete("1234");
DAO.Organsation.delete("1234");