Java 在两个不同的接口实现中重复代码
对于每个实体,我都在创建一个控制器、一个服务和一个DAO。我现在有大约8个实体和这些类。让我们以我的类分类和产品为例 类CategorieDaoImpl实现CategorieDao中的方法 类ProductDaoImpl实现ProductDao中的方法 正如您所看到的,除了参数和save的参数之外,这两个类的代码非常相似 Intellij告诉我这是重复的代码,但它并没有像在类中重复代码时那样给我一个解决方案。你知道我该如何解决这个问题并让它变得更好吗 提前谢谢 编辑:Java 在两个不同的接口实现中重复代码,java,duplicates,code-duplication,Java,Duplicates,Code Duplication,对于每个实体,我都在创建一个控制器、一个服务和一个DAO。我现在有大约8个实体和这些类。让我们以我的类分类和产品为例 类CategorieDaoImpl实现CategorieDao中的方法 类ProductDaoImpl实现ProductDao中的方法 正如您所看到的,除了参数和save的参数之外,这两个类的代码非常相似 Intellij告诉我这是重复的代码,但它并没有像在类中重复代码时那样给我一个解决方案。你知道我该如何解决这个问题并让它变得更好吗 提前谢谢 编辑: 大多数Dao类都有相同的C
大多数Dao类都有相同的CRU方法:get、insert、update、delete。大多数情况下,只有参数不同。最简单的解决方案是:
public boolean insertGeneric(Object whatever) {
Session session = null;
try {
session = super.getConnection();
session.getTransaction().begin();
session.save(whatever);
session.getTransaction().commit();
return true;
} catch (HibernateException e) {
e.printStackTrace();
return false;
} finally {
closeConnection(session);
}
}
当然,更一般的答案可能是使用某种类型参数而不是对象
如果没有这样的基类,那么下一个最好的方法是识别一个公共基类接口,或者识别一个您想要保存的所有对象都可以/应该/需要实现的东西
换句话说:您的选项空间很大程度上取决于session.save的实际签名 最简单的解决方案是:
public boolean insertGeneric(Object whatever) {
Session session = null;
try {
session = super.getConnection();
session.getTransaction().begin();
session.save(whatever);
session.getTransaction().commit();
return true;
} catch (HibernateException e) {
e.printStackTrace();
return false;
} finally {
closeConnection(session);
}
}
当然,更一般的答案可能是使用某种类型参数而不是对象
如果没有这样的基类,那么下一个最好的方法是识别一个公共基类接口,或者识别一个您想要保存的所有对象都可以/应该/需要实现的东西
换句话说:您的选项空间很大程度上取决于session.save的实际签名 一个抽象可插入类可以解决这个问题,该类有一些公共布尔insertT来保存您的代码:
public abstract class AbstractInsertable<T> extends ... {
public boolean insert(T t) {
Session session = null;
try {
session = super.getConnection();
session.getTransaction().begin();
session.save(t);
session.getTransaction().commit();
return true;
} catch (HibernateException e) {
e.printStackTrace();
return false;
} finally {
closeConnection(session);
}
}
[...]
}
在不知道closeSession…(关闭会话)的确切实现的情况下,如果您没有执行nullcheck,那么可能会抛出NPE,我也不会感到惊讶。如果会话是,则可以使用。如果不是,您可以利用您的优势:
Optional<Session> optionalSession = Optional.empty();
try {
optionalSession = Optional.of(super.getConnection());
session = optionalSession.get();
[...]
} finally {
optionalSession.ifPresent(this::closeSession);
}
可以使用一个抽象可插入类来解决这个问题,该类有一些公共布尔插入来保存代码:
public abstract class AbstractInsertable<T> extends ... {
public boolean insert(T t) {
Session session = null;
try {
session = super.getConnection();
session.getTransaction().begin();
session.save(t);
session.getTransaction().commit();
return true;
} catch (HibernateException e) {
e.printStackTrace();
return false;
} finally {
closeConnection(session);
}
}
[...]
}
在不知道closeSession…(关闭会话)的确切实现的情况下,如果您没有执行nullcheck,那么可能会抛出NPE,我也不会感到惊讶。如果会话是,则可以使用。如果不是,您可以利用您的优势:
Optional<Session> optionalSession = Optional.empty();
try {
optionalSession = Optional.of(super.getConnection());
session = optionalSession.get();
[...]
} finally {
optionalSession.ifPresent(this::closeSession);
}
通常有两种方法:将公共代码放入一个公共基类中,然后从中扩展类。或者将公共代码放入另一个类中,并在类中使用该类的实例。尝试使用第二种方法,即组合优先于继承。除此之外:过于宽泛和/或基于观点。通常有两种方法:将公共代码放入一个公共基类中,然后从中扩展类。或者将公共代码放入另一个类中,并在类中使用该类的实例。尝试使用第二种方法,即组合优先于继承。除此之外:太宽泛和/或基于观点。@Andreas哪一个优先?谢谢,修正了。@Andreas哪种覆盖?谢谢,修正了。非常感谢你的回答。我现在正在尝试实现它,看看它是如何工作的。再次感谢@ProxiHenn我刚注意到你的代码中有些东西。我在上一节更新了我的答案。也许你想看看。我在CloseSession中对会话进行空检查。非常感谢你的回答。我现在正在尝试实现它,看看它是如何工作的。再次感谢@ProxiHenn我刚注意到你的代码中有些东西。我在上一节更新了我的答案。也许你想看看。我正在closeSession中对会话进行空检查