模板方法模式

时间:2009-08-14 08:10:08

标签: java spring template-method-pattern

如果我的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() ;
    }
}

3 个答案:

答案 0 :(得分:4)

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

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模板而不是自己编写 - 他们已经过试验和测试,并解决了嵌套事务等会遇到的问题。

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

尼克    我要使用的“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();
            }
        }

  }
}