我现在很难不在我正在研究的Java程序中重复自己.
说,我需要声明很多基本上按以下方式构造的方法:
public SomeEntity doSomething (String someAttribute, String anotherAttribute) {
EntityManager em = this.createEntityManager();
EntityTransaction tx = null;
try {
/*
* ... independent logic ...
*/
tx = em.getTransaction();
} catch (RuntimeException e) {
if (tx != null && tx.isActive()) {
tx.rollback();
}
throw e;
} finally {
em.close();
}
return something;
}
Run Code Online (Sandbox Code Playgroud)
所有方法的方法体都需要包含用于资源管理的元素.
"独立逻辑"本身也会相当复杂,因此将try/catch语句放在一个单独的方法中并不会真正起作用.
我想避免重复此代码.在这些情况下应用哪些最佳实践?
nos*_*nos 35
创建一个界面:
public interface EntityManagerAction {
public void execute(EntityManager em);
}
Run Code Online (Sandbox Code Playgroud)
和实用类:
public class EntityUtil {
public static void executeWithEntityManager(EntityManagerAction action) {
EntityManager em = someHowCreateEntityManager();
EntityTransaction tx = null;
try {
action.execute(em);
tx = em.getTransaction();
} catch (RuntimeException e) {
if (tx != null && tx.isActive()) {
tx.rollback();
}
throw e;
} finally {
em.close();
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在您可以在EntityUtil类中重复使用样板,并且您的代码变为:
public SomeEntity doSomething (String someAttribute, String anotherAttribute) {
Something something;
EntityUtil.executeWithEntityManager(new EntityManagerAction() {
public void execute(EntityManager em ) {
/*
* ... independent logic ...
*/
//use the passed in 'em' here.
}
});
return something;
}
Run Code Online (Sandbox Code Playgroud)
另请参阅什么是"执行"成语?
如果所有finally子句都用于关闭Streams等(实现的任何东西AutoCloseable),则可以使用try-with-resources(如其中一条注释中所建议的)来删除该finally子句.
但是,如果您需要更通用的解决方案,并且Exception在finally子句中捕获了相同类型的s和相同类型的处理,则可以创建一个抽象类,例如:
abstract class SensitiveBlockHandler {
public void handle() {
try {
doHandling();
} catch (SomeException | AnotherException e) {
// TODO: handle exceptions here ...
} finally {
// TODO: cleanup here ...
}
}
protected abstract void doHandling();
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以创建内部类来处理不同的情况,或者作为匿名类.代码应该类似于:
public SomeEntity doSomething (String someAttribute, String anotherAttribute) {
new SensitiveBlockHandler() {
protected void doHandling() {
/*
* ... independent logic ...
*/
}
}.handle();
return something;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4288 次 |
| 最近记录: |