Java 在两个不同的接口实现中重复代码

Java 在两个不同的接口实现中重复代码,java,duplicates,code-duplication,Java,Duplicates,Code Duplication,对于每个实体,我都在创建一个控制器、一个服务和一个DAO。我现在有大约8个实体和这些类。让我们以我的类分类和产品为例 类CategorieDaoImpl实现CategorieDao中的方法 类ProductDaoImpl实现ProductDao中的方法 正如您所看到的,除了参数和save的参数之外,这两个类的代码非常相似 Intellij告诉我这是重复的代码,但它并没有像在类中重复代码时那样给我一个解决方案。你知道我该如何解决这个问题并让它变得更好吗 提前谢谢 编辑: 大多数Dao类都有相同的C

对于每个实体,我都在创建一个控制器、一个服务和一个DAO。我现在有大约8个实体和这些类。让我们以我的类分类和产品为例

类CategorieDaoImpl实现CategorieDao中的方法

类ProductDaoImpl实现ProductDao中的方法

正如您所看到的,除了参数和save的参数之外,这两个类的代码非常相似

Intellij告诉我这是重复的代码,但它并没有像在类中重复代码时那样给我一个解决方案。你知道我该如何解决这个问题并让它变得更好吗

提前谢谢

编辑:


大多数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中对会话进行空检查