设计模式-模版模式

模板模式UML

在这里插入图片描述
多数情况下,可以将部分逻辑进行抽象,在抽象类中定义好如何使用这些抽象方法,然后抽象方法的具体实现交给其他人实现,或者在以后实现,客户端只需要依赖抽象类,而不需要依耐具体的实现,这就可以使得在业务运行的过程中,我们可以根据业务的变换来实现不同的子类。而且这里仅需要的一步就是继承AbastractClass,重写父类中的primitive方法即可,在客户端中,只需要在配置文件中配置成对应的子类即可。

模版模式的实现

1、模版类

public abstract class AbstractClass {
	public abstract void primitiveOperation1();
	public abstract void primitiveOperation2();
	public void templateMethod(){
		//在模版方法中,不一定只是简单的调用这两个方法,当然还可以是更复杂的逻辑
		primitiveOperation1();
		primitiveOperation2();
	}
}

2、在子类中实现模版类中的抽象方法

public class ConcreteClass extends AbstractClass {
	@Override
	public void primitiveOperation1() {
		System.out.println("我是子类中的逻辑1,为父类中的模版方法提供处理方法");
	}

	@Override
	public void primitiveOperation2() {
		System.out.println("我是子类中的逻辑2,为父类中的模版方法提供处理方法");
	}
}

3、客户端测试类

public class Main {
	public static void main(String[] args) {
		AbstractClass abstractClass = new ConcreteClass();	//这里可以借用反射来决定具体采用哪个类
		abstractClass.templateMethod();
	}
}

HibernateTemplate中的模版模式

使用过Spring框架和Hibernate的读者应该会对该类比较熟悉,HibernateTemplate类中采用的亦是模版模式。
1、原HibernateTemplate中的execute部分

public <T> T execute(HibernateCallback<T> action) throws DataAccessException {
  	return doExecute(action, false, false);
}

protected <T> T doExecute(HibernateCallback<T> action, boolean enforceNewSession, boolean enforceNativeSession)
   throws DataAccessException {
   //...代码省略
  	Assert.notNull(action, "Callback object must not be null");
  	//...代码省略
   	T result = action.doInHibernate(sessionToExpose);
   	//...代码省略
 }

事实上,这里的doExecute就是模版方法,相当于UML图中templateMethod,然后调用了HibernateCallback中的doInHibernate()方法,而该方法正是要求我们重写的方法,与我们上面介绍的模版模式稍微不同的地方是:不是通过继承HibernateTtemplate类来重写其中的抽象方法,而是通过继承HibernateCallback类来重写其中的抽象方法,只需要在调用的时候将HibernateCallback对象传到doExecute()中即可,然后在doExecute()中调用的是HibernateCallback的doInHibernate()方法。
简单的说,就是将上方UML类图中原有的模版类进行了拆分,一个是模版类,一个是抽象方法类。模版类调用抽象方法类中的方法

接下来笔者模拟HibernateTemplate来实现一个MyHibernateTemplate
1、模版类

package template;
public class MyHibernateTemplate {
	public <T> T execute(MyHibernateCallback<T> action){
		return this.doExecute(action);
	}
	public <T> T doExecute(MyHibernateCallback<T> action){
		T result = action.doInHibernate();
		return result;
	}
}

2、将具体的操作抽象成一个接口

package template;
public interface MyHibernateCallback<T>{
	public T doInHibernate();
}

3、Java Bean,这里应该从数据库中读取

package template;
public class User {
	private Integer id;
	private String username;
	private String password;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
}

4、客户端测试类

package template;

public class Main {
	public static void main(String[] args) {
		MyHibernateTemplate template = new MyHibernateTemplate();
		User u = template.doExecute(new MyHibernateCallback<User>() {
			@Override
			public User doInHibernate() {
				//事实上这个地方应该从数据库中读取,当然这里会用到Hibernate框架从数据库中读取数据
				User user = new User();
				user.setId(1);
				user.setUsername("123");
				user.setPassword("abc");
				return user;
			}
		});
		System.out.println("id:" + u.getId() + ",username:" + u.getUsername() + ",password:" + u.getPassword());
	}
}

输出结果:
id:1,username:123,password:abc

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值