【问题标题】:template method pattern模板方法模式
【发布时间】:2016-02-14 00:17:10
【问题描述】:

如果我的 childClass 方法 getInfoFromDB() 和 saveToDB() 需要执行不同的逻辑,我可以知道如何创建 childClass 吗?

public abstract class BaseClass {
    public abstract Object doTransaction();
    public Object executeTrans() {
          //do something
          tx.begin();            
          this.doTransaction();
          tx.commit();

    }
}
public childClass extends BaseClass{
    @Override
    public Object doTransaction(){
        //overide to get something from database so can only be used for getInfoFromDB() and not for saveToDB()
        return something;
    }
    public List<String> getInfoFromDB(){
        super.executeTrans();
    }
    public void saveToDB(){
        super.executeTrans() ;
    }
}

【问题讨论】:

    标签: java spring template-method-pattern


    【解决方案1】:

    在这种情况下,您应该使用模板模式,如下所示:

    public abstract class BaseClass 
    {      
      public Object executeTrans(Template template) 
      {
        tx.begin();            
        template.doTransaction();
        tx.commit();    
      }
    }
    
    public interface Template
    {
      public void doTransaction();
    }
    
    public childClass extends BaseClass
    {
      public List<String> getInfoFromDB()
      {
        executeTrans(
          new Template()
          {
            public void doTransaction() 
            {
              ...do get info from DB here.
            }
          }
        );
      }
    
      public void saveToDB()
      {
        executeTrans(
          new Template()
          {
            public void doTransaction() 
            {
              ...do save to DB here.
            }
          }
        );
      }
    }
    

    也就是说,我建议您使用 Spring JDBC 模板类,而不是使用您自己的 - 它们已经过尝试和测试,并且已经解决了您在使用嵌套事务等时会遇到的问题。

    【讨论】:

    • 如果我错了,请纠正我。通过让 childClass 扩展 BaseClass; saveToDB() 和 getInfoFromDB() 的 executeTrans() 方法将调用相同的 executeTrans() 的 tx.begin 和 tx.close()。这会好吗?还是应该是单独的新瞬间?
    • 我可以知道你放在那里的“模板”类型是什么吗?
    • 模板类就是这个样子 --> class Template(){ public void doTransaction(){}; } ?
    • 是的,两种方法都将使用相同的 tx 对象。在不了解 tx 是什么以及对象生命周期的更多信息的情况下,很难说它是否正常,尽管事务管理通常与您正在使用的数据库连接相关,因此它可能不应该是成员变量。就像我说的,看看 Spring JDBC 模板是如何工作的——它们非常简单,可以处理所有这些问题。
    • 模板界面只是为了演示模板模式。为了清楚起见,我将添加它的定义。
    【解决方案2】:

    将包含不同逻辑的 Runnable 传递给 executeTrans() 方法。

    但是,我不确定模板方法模式是否真的是您需要的(以及它如何处理回滚?)。您可能想研究一个允许declarative transactions 的框架,例如 Spring。

    【讨论】:

      【解决方案3】:

      尼克, 我要使用的“tx”如下所示。从代码来看,最佳实践是生命周期是可以的,因为它被 savetodb() 和 getinfofromdb() 调用

      public abstract class BaseClass 
      {      
        public Object executeTrans(Template template) 
        {
              // PersistenceManager pm = ...;
              Transaction tx = pm.currentTransaction();
              try {
                  tx.begin();
                   template.doTransaction();
                  tx.commit();
              } finally {
                  if (tx.isActive()) {
                      tx.rollback();
                  }
              }
      
        }
      }
      

      【讨论】:

      • 我对 JDO 知之甚少(我认为这就是您正在使用的),但除了 finally 块之外,它看起来差不多 - 虽然这可能会起作用,但如果发生异常。
      猜你喜欢
      • 1970-01-01
      • 2011-12-30
      • 1970-01-01
      • 1970-01-01
      • 2021-03-20
      • 1970-01-01
      • 2019-08-23
      • 2013-01-11
      • 1970-01-01
      相关资源
      最近更新 更多