Java模板方法的使用方式有哪些

其他教程   发布日期:2023年07月04日   浏览次数:558

这篇文章主要介绍了Java模板方法的使用方式有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java模板方法的使用方式有哪些文章都会有所收获,下面我们一起来看看吧。

为什么我会想到使用模板方法呢?

在日常开发中,我们经常需要使用编程式事务来解决一些实在的业务问题。以Hibernate框架为例(其实对于ORM框架来说,都大同小异。我们公司使用的是Hiberante,所以这里就以Hibernate为例了),我们实现一个编程式事务如下:

  1. SessionFactory sessionFactory = (SessionFactory) applicationContext.getBean("sessionFactory");
  2. Session session = sessionFactory.openSession();
  3. try {
  4. session.beginTransaction();
  5. String sql = "update table set A = :a where id = :id";
  6. session.createNativeQuery(sql)
  7. .setParameter("a", "a")
  8. .setParameter("id", id)
  9. .executeUpdate();
  10. session.getTransaction().commit();
  11. } catch (Exception e) {
  12. session.getTransaction().rollback();
  13. } finally {
  14. session.close();
  15. }

我们看上述的代码是不是有一种很乱的感觉,还要自己去写try{}catch{}finally{}。而且当我们代码中有很多地方都应用了编程式事务的话,那么我们的代码会显得有些臃肿。尤其对于我这种强迫症患者来说,哈哈!!

既然如此,我们肯定要想一种方式去优化一下,至少让它看起来更优美一些。我这里选择使用模板方法来改造一下。

什么是模板方法设计模式?

模板方法说白了就是将一段代码模板化,将通用的代码段抽取出来,并提供一些自定义的接口去定制的特定位置的某些业务功能。

根据我的理解,模板方法的核心思想就是 重写 。我们在模板中的指定位置提供一个外部可编辑的接口,让调用者可以根据需求去随意重写这个接口来达到他的目的。

其实在Spring中也广泛使用的模板方法,当我们学习Spring源码的时候会发现,实际上Bean的生命周期中就使用了模板方法。我们可以根据自己的需求在Bean生命周期的各个阶段去做一些事情。

代码优化

首先我们先维护一个抽象的模板类,这个类里包含了三个公开的方法,用来提供为调用者去定制使用。

  1. public abstract class TransactionManagerTemplate {
  2. /**
  3. * 处理事务中的实际要处理的业务代码
  4. */
  5. public void handle() {}
  6. /**
  7. * 异常处理
  8. */
  9. public void exceptionHandle() {}
  10. /**
  11. * finally处理
  12. */
  13. public void finallyHandle() {}
  14. }

然后我们创建一个事务管理器,封装一个runTransaction方法,里面就包含了上面那边不忍直视的代码。然后我们将Session和抽象的模板类作为参数传入

并且将抽象的模板类中的三个公开方法填入到try{}catch{}finally{}中的各个位置。

  1. @Component
  2. public class TransactionManager {
  3. @Autowired
  4. private ApplicationContext applicationContext;
  5. /**
  6. * 默认SessionFactory
  7. */
  8. public static final String DEFAULT_SESSION_FACTORY = "sessionFactory";
  9. /**
  10. * 执行事务
  11. * @param session
  12. * @param transactionManagerTemplate
  13. *
  14. * 使用案例:
  15. * Session session = transactionManager.getSession();
  16. * transactionManager.runTransaction(session, new TransactionManagerTemplate() {
  17. * // 实际要重写的接口
  18. * });
  19. */
  20. public void runTransaction(Session session, TransactionManagerTemplate transactionManagerTemplate) {
  21. try {
  22. session.beginTransaction();
  23. transactionManagerTemplate.handle();
  24. session.getTransaction().commit();
  25. } catch (Exception e) {
  26. transactionManagerTemplate.exceptionHandle();
  27. session.getTransaction().rollback();
  28. } finally {
  29. transactionManagerTemplate.finallyHandle();
  30. session.close();
  31. }
  32. }
  33. /**
  34. * 获取默认SessionFactory
  35. * @return
  36. */
  37. public SessionFactory getSessionFactory() {
  38. return getSessionFactory(DEFAULT_SESSION_FACTORY);
  39. }
  40. /**
  41. * 获取指定SessionFactory
  42. * @param beanName 指定SessionFactory的BeanName
  43. * @return
  44. */
  45. public SessionFactory getSessionFactory(String beanName) {
  46. SessionFactory sessionFactory = (SessionFactory) applicationContext.getBean(beanName);
  47. if(sessionFactory == null) {
  48. throw new BAPException("不存在BeanName为【{}】的SessionFactory", beanName);
  49. }
  50. return sessionFactory;
  51. }
  52. /**
  53. * 获取默认Session
  54. * @return
  55. */
  56. public Session getSession() {
  57. return getSessionFactory(DEFAULT_SESSION_FACTORY).openSession();
  58. }
  59. /**
  60. * 获取指定SessionFactory下的Session
  61. * @param sessionFactoryBeanName 指定SessionFactory的BeanName
  62. * @return
  63. */
  64. public Session getSession(String sessionFactoryBeanName) {
  65. return getSessionFactory(sessionFactoryBeanName).openSession();
  66. }
  67. }

我们在业务代码中想要再次使用编程式事务时,就可以通过如下方式调用:

  1. Session session = transactionManager.getSession();
  2. transactionManager.runTransaction(session, new TransactionManagerTemplate() {
  3. @Override
  4. public void handle() {
  5. // try中要添加的业务逻辑
  6. }
  7. @Override
  8. public void exceptionHandle() {
  9. // catch中要添加的业务逻辑
  10. }
  11. @Override
  12. public void finallyHandle() {
  13. // finally中要添加的业务逻辑
  14. }
  15. });

以上就是Java模板方法的使用方式有哪些的详细内容,更多关于Java模板方法的使用方式有哪些的资料请关注九品源码其它相关文章!