重构常用方法页眉和页脚

发布于 2024-10-11 16:31:49 字数 679 浏览 2 评论 0原文

我在很多方法中都出现了以下页眉和页脚代码块。有没有更干净的方法来实现这个?

 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
    }
}

I have the following chunk of header and footer code appearing in alot of methods. Is there a cleaner way of implementing this?

 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();
 }

The class in question is actually an EJB 2.0 SessionBean which looks like:

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

酒浓于脸红 2024-10-18 16:31:49

如果您可以将 // 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() 方法中,这种模式就适合。

If you can fit the // do some work into a strategy pattern, you could create a method containing your boilerplate code passing the action as parameter;

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();
 }

This pattern will fit as long as you do not have to pass many parameters into the execute() method.

荭秂 2024-10-18 16:31:49

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

 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() 方法

You could introduce an abstract class that collects all this boilerplate stuff. Advantage: avoids unnecessary duplication of code. Here's one approach:

 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();
}

Your implementations simply subclass AbstractBase and implement the doStuff() method

离笑几人歌 2024-10-18 16:31:49
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 。

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
        ...
    }
});

You can use your own interface instead of Runnable if you need to throw specific exceptions.

萤火眠眠 2024-10-18 16:31:49

您可能想要这样的东西:

 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 惯用法允许您编写一次代码(尽管它仍然非常冗长)。

You probably want something like:

 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();
 }

I've taken the liberty of rolling back no matter what exception, and avoided the issue about which checked exceptions to declare. As Vincent and Robert's answers mention, using the Execute Around idiom allows you to write the code once (although it's still highly verbose).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文