`
lijj_72
  • 浏览: 21990 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Spring 模板方法 vs 经典模板方法设计模式

阅读更多

Spring 模板方法 vs 经典模板方法设计模式

         李俊杰 

概述

模板方法模式是GOF设计模式中很典型的设计模式,其意图是由抽象父类控制顶级逻辑,并把基本操作的实现推迟到子类去实现,这是通过继承的手段来达到对象的复用。Spring模板方法模式实际是模板方法模式和回调模式的结合,Spring几乎所有的外接扩展都采用这种模式,如JNDIJMSJCA CCIJDBCORM中的Hiberate3jdoToplink等扩展都采用模板方法模式来扩展。

<!----><o:p> </o:p>

经典的模板方法设计模式

开闭原则是指一个软件实体应该对扩展开放,对修改关闭。先制定一个顶级逻辑框架,而将逻辑的细节留给具体的子类去实现。如图所示,面向接口编程,client只需调用Template接口中的execute方法,在AbstractTemplate抽象类的示例代码所示,实现execute()方法,但在execute()方法中制定所需的大的步骤,调用如subExecute1(),subExecute2(),subExecute3()方法来完成,但AbstractTemplate抽象类把subExecute1(),subExecute2()设置为抽象方法,由子类来实现,subExecute3()给出了缺省实现,也可由子类来覆盖,如SubTemplateImpl2类。

 

 

<!----><v:shapetype o:spt="75" coordsize="21600,21600" filled="f" stroked="f" id="_x0000_t75" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t"><v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"></v:f><v:f eqn="sum @0 1 0"></v:f><v:f eqn="sum 0 0 @1"></v:f><v:f eqn="prod @2 1 2"></v:f><v:f eqn="prod @3 21600 pixelWidth"></v:f><v:f eqn="prod @3 21600 pixelHeight"></v:f><v:f eqn="sum @0 0 1"></v:f><v:f eqn="prod @6 1 2"></v:f><v:f eqn="prod @7 21600 pixelWidth"></v:f><v:f eqn="sum @8 21600 0"></v:f><v:f eqn="prod @7 21600 pixelHeight"></v:f><v:f eqn="sum @10 21600 0"></v:f></v:formulas><v:path o:extrusionok="f" o:connecttype="rect" gradientshapeok="t"></v:path><o:lock v:ext="edit" aspectratio="t"></o:lock></v:shapetype><v:shape id="_x0000_i1025" type="#_x0000_t75" style="WIDTH: 369pt; HEIGHT: 270.75pt"><v:imagedata src="file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\msohtml1\03\clip_image001.emz" o:title=""></v:imagedata></v:shape>

public abstract class AbstractTemplate implements TemplateInterface

{

       public void execute()

       {

              subExecute1();

              subExecute2();

              subExecute3();

       }

       protected abstract void subExecute1();

       protected abstract void subExecute2();

       protected  void subExecute3()

       {

<o:p> </o:p>

       }

<o:p> </o:p>

}

<o:p></o:p> 

Spring中也有对经典模板方法模式的运用,以Hibernate3为例说明

AbstractSessionFactoryBean模板方法afterPropertiesSet(),调用抽象方法buildSessionFactory()和缺省实现方法afterSessionFactoryCreation()<o:p></o:p>

public void afterPropertiesSet() throws Exception {<o:p></o:p>

       SessionFactory rawSf = buildSessionFactory();<o:p></o:p>

       this.sessionFactory = wrapSessionFactoryIfNecessary(rawSf);<o:p></o:p>

       afterSessionFactoryCreation();<o:p></o:p>

    }<o:p></o:p>

protected abstract SessionFactory buildSessionFactory() throws Exception;<o:p></o:p>

    protected void afterSessionFactoryCreation() throws Exception {<o:p></o:p>

    }

在其子类中LocalSessionFactoryBean中则有相关子步骤方法的实现<o:p></o:p>

protected SessionFactory buildSessionFactory() throws Exception {<o:p></o:p>

       … //代码太长了<o:p></o:p>

    return newSessionFactory(config);<o:p></o:p>

}

protected void afterSessionFactoryCreation() throws Exception {<o:p></o:p>

       if (this.schemaUpdate) {<o:p></o:p>

           DataSource dataSource = getDataSource();<o:p></o:p>

           if (dataSource != null) {              <o:p></o:p>

              configTimeDataSourceHolder.set(dataSource);<o:p></o:p>

           }<o:p></o:p>

           try {<o:p></o:p>

              updateDatabaseSchema();<o:p></o:p>

           }<o:p></o:p>

           finally {<o:p></o:p>

              if (dataSource != null) {<o:p></o:p>

                  // Reset DataSource holder.<o:p></o:p>

                  configTimeDataSourceHolder.set(null);<o:p></o:p>

              }<o:p></o:p>

           }<o:p></o:p>

       }<o:p></o:p>

    }

Spring模板方法模式的运用

Spring几乎所有的外接扩展,都采用模板方法模式,为了说明的更清楚些,用Hiberate3的扩展举例说明。

回调函数接口HibernateCallback

HibernateCallback接口,在该接口中只声明了一个方法doInHibernate(Session session),这个方法其实是由子类来实现的子步骤方法

public interface HibernateCallback {<o:p></o:p>

    Object doInHibernate(Session session) throws HibernateException, SQLException;<o:p></o:p>

}

模板方法类HibernateTemplate的模板方法execute()

HibernateTemplate类的execute()方法,值得注意的是execute()方法的一个参数是HibernateCallback接口,这就是Spring模板方法模式的核心和前提,为了清楚模板方法模式,把相关的事务处理及异常处理等代码去掉,这样可以清楚地看出HibernateCallback接口的 action.doInHibernate(sessionToExpose)仅仅是其中的一个步骤,并且action就是execute模板方法方法的第一个参数HibernateCallback接口的实际实现类。

public Object execute(HibernateCallback action, boolean exposeNativeSession) throws DataAccessException {        <o:p></o:p>

              previousFlushMode = applyFlushMode(session,existingTransaction);<o:p></o:p>

           enableFilters(session);<o:p></o:p>

           Session sessionToExpose = (exposeNativeSession ? session : createSessionProxy(session));<o:p></o:p>

           Object result = action.doInHibernate(sessionToExpose);<o:p></o:p>

           flushIfNecessary(session, existingTransaction);<o:p></o:p>

           return result;<o:p></o:p>

       <o:p></o:p>

    }

模板方法类HibernateTemplate的其他对外方法的匿名类方法实现回调

HibernateTemplate类中实现HibernateCallback接口的却是匿名类,如get方法<o:p></o:p>

public Object get(final String entityName, final Serializable id, final LockMode lockMode)<o:p></o:p>

           throws DataAccessException {<o:p></o:p>

<o:p> </o:p>

       return execute(new HibernateCallback() {<o:p></o:p>

           public Object doInHibernate(Session session) throws HibernateException {<o:p></o:p>

              if (lockMode != null) {<o:p></o:p>

                  return session.get(entityName, id, lockMode);<o:p></o:p>

              }<o:p></o:p>

              else {<o:p></o:p>

                  return session.get(entityName, id);<o:p></o:p>

              }<o:p></o:p>

           }<o:p></o:p>

       }, true);<o:p></o:p>

    }

load方法

public Object load(final Class entityClass, final Serializable id, final LockMode lockMode)<o:p></o:p>

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics