Exceptions en java: Comment réduire le code répété

Ommadawn:

J'utilise un modèle Data Access Object (DAO) en Java et j'ai le même morceau de code répété sur mes fichiers. La chose est somethimng comme ceci:

public User getById(int id) throws BDException {
    Session session = sessionFactory.getCurrentSession();
    Transaction tx = session.getTransaction();

    try {
        tx.begin();
        Query query = session.createQuery("SELECT u FROM User u WHERE u.id=:id");
        query.setString("id", id);
        User user = (User) query.uniqueResult();
        tx.commit();

        return user;
    }
    catch(javax.validation.ConstraintViolationException | org.hibernate.exception.ConstraintViolationException cve) {
        try {
            if(tx.getStatus() == TransactionStatus.ACTIVE) {
                tx.rollback();
            }
        }
        catch(Exception exc) {
            LOGGER.error("Error rollback in method='" + getMethodName() + "'");
        }
        throw new BDException(cve);
    }
    catch(RuntimeException ex) {
        try {
            if(tx.getStatus() == TransactionStatus.ACTIVE) {
                tx.rollback();
            }
        }
        catch(Exception exc) {
            LOGGER.error("Error rollback in method='" + getMethodName() + "'");
        }
        throw ex;
    }
    catch(Exception ex) {
        try {
            if(tx.getStatus() == TransactionStatus.ACTIVE) {
                tx.rollback();
            }
        }
        catch(Exception exc) {
            LOGGER.error("Error rollback in method='" + getMethodName() + "'");
        }
        throw new RuntimeException(ex);
    }
}

Eh bien, je veux que vous regardez la part de la prise. Je l'ai répété dans chaque méthode que j'ai. Si ce code était simple, je pourrais créer une méthode, mettre tout ce code à l'intérieur et appeler la méthode au lieu de répétition du code. Le problème est que ce n'est pas du code normal, ce sont des exceptions.

Alors, est-il une solution au code de réutilisation et de ne pas répéter (copier-coller) le code dans chaque méthode?

Merci!

VoiceOfUnreason:

est-il une solution au code de réutilisation et de ne pas répéter (copier-coller) le code dans chaque méthode?

Il y a.

La « viande » de votre fonction est ici

    Query query = session.createQuery("SELECT u FROM User u WHERE u.id=:id");
    query.setString("id", id);
    User user = (User) query.uniqueResult();

Si vous strabisme très attentivement, vous pouvez voir que c'est une « fonction » qui accepte un Sessioncomme argument, et retourne un User. Qu'est - ce que vous pouvez faire est de faire de cette fonction un argument à la chose qui fait toute la gestion des exceptions.

En Java, cela signifie généralement l'expression de la fonction comme un « objet »

User MyCrazyFunctionThing::uniqueResult(Session session) {
    Query query = session.createQuery(this.sql);
    query.setString("id", this.id);
    return query.uniqueResult();
}

User DatabaseGateway::execute(MyCrazyFunctionThing q) {
    Session session = sessionFactory.getCurrentSession();
    Transaction tx = session.getTransaction();

    try {
        tx.begin();
        User user = q.uniqueResult(session)
        tx.commit();

        return user;
    } catch (...) {
        // ...
    }
}

Tout de suite, vous pouvez le transformer en logique qui peut être exécutée chaque fois que vous essayez de chercher un utilisateur unique à partir d'une session.

Vous pouvez faire ce encore plus générale avec les génériques

interface MyCrazyGenericThing<T> {
    T uniqueResult(Session session);
}

class MyCrazyFunctionThing implements MyCrazyGenericThing<User> {
    User uniqueResult(Session session) {
        Query query = session.createQuery(this.sql);
        query.setString("id", this.id);
        return query.uniqueResult();
    }
}

<T> T DatabaseGateway::execute(MyCrazyGenericThing<T> q) {
    Session session = sessionFactory.getCurrentSession();
    Transaction tx = session.getTransaction();

    try {
        tx.begin();
        T result = q.uniqueResult(session)
        tx.commit();

        return result;
    } catch (...) {
        // ...
    }
}

Ce que vous voyez ici est le modèle de stratégie utilisé pour spécifier quel code devrait fonctionner dans la logique de transaction.

Je suppose que tu aimes

Origine http://43.154.161.224:23101/article/api/json?id=185255&siteId=1
conseillé
Classement