重构常用方法页眉和页脚

时间:2011-01-14 09:37:31

标签: java refactoring

我在大量方法中出现了以下大量的页眉和页脚代码。有没有更清晰的方法来实现这个?

 Session sess = factory.openSession();
 Transaction tx;
 try {
     tx = sess.beginTransaction();
     //do some work
     ...
     tx.commit();
 }
 catch (Exception e) {
     if (tx!=null) tx.rollback();
     throw e;
 }
 finally {
     sess.close();
 }

有问题的类实际上是一个EJB 2.0 SessionBean,它看起来像:

public class PersonManagerBean implements SessionBean {
    public void addPerson(String name) {
        // boilerplate
        // dostuff
        // boilerplate
    }

    public void deletePerson(Long id) {
        // boilerplate
        // dostuff
        // boilerplate
    }
}

4 个答案:

答案 0 :(得分:6)

如果您可以将// do some work放入策略模式中,则可以创建一个包含样板代码的方法,将该操作作为参数传递;

void executeWork(WorkInterface work) {
Session sess = factory.openSession();
 Transaction tx;
 try {
     tx = sess.beginTransaction();

     work.execute();

     tx.commit();
 }
 catch (Exception e) {
     if (tx!=null) tx.rollback();
     throw e;
 }
 finally {
     sess.close();
 }

只要您不必将许多参数传递到execute()方法,此模式就适合。

答案 1 :(得分:2)

您可以引入一个抽象类来收集所有这些样板文件。优点:避免不必要的代码重复。这是一种方法:

 public abstract AbstractBase {

   public void doSomthing() {
    Session sess = factory.openSession();
    Transaction tx;
    try {
       tx = sess.beginTransaction();
       doStuff();
       tx.commit();
    }
    catch (Exception e) {
      if (tx!=null) tx.rollback();
      throw e;
    }
    finally {
     sess.close();
    }
   }

   public abstract void doStuff();
}

您的实现只是将AbstractBase子类化并实现doStuff()方法

答案 2 :(得分:1)

private void withTransactedSession(Runnable runnable)
{
   Session sess = factory.openSession();
   Transaction tx;
   try {
       tx = sess.beginTransaction();
       runnable.run();
       tx.commit();
   }
   catch (Exception e) {
       if (tx!=null) tx.rollback();
       throw e;
   }
   finally {
       sess.close();
   }
}

...

withTransactedSession(new Runnable()
{
    public void run()
    {      
        //do some work
        ...
    }
});

如果您需要抛出特定的例外情况,可以使用自己的界面而不是Runnable

答案 3 :(得分:0)

您可能需要以下内容:

 final Session sess = factory.openSession();
 try {
     boolean committed = false;
     final Transaction tx = sess.beginTransaction();
     try {
         //do some work
         ...
         tx.commit();
         committed = true;
     } finally {
         if (!committed) {
             tx.rollback();
         }
     }
 } finally {
     sess.close();
 }

无论出现什么异常,我都可以自由回滚,并避免了关于要声明哪些已检查异常的问题。正如Vincent和Robert的回答所提到的那样,使用Execute Around成语可以让你编写一次代码(虽然它仍然非常冗长)。