Java模版方法模式

1. 什么是模版方法?

--算法执行的统一框架,模版方法模式定义了一个操作中的算法骨架,将一些步骤延迟到子类实现,使得子类可以在不改变算法结构的同时就重新定义该算法的某些特定步骤。

----Step1、Step2、....Step n


2.

模板方法(使用抽象父类定义框架)


抽象父类,为所有子类提供一个算法框架


步骤:

(1)、定义一个公共的抽象父类

(2)、定义一个公共 final 的方法(封装所有子类都要遵循的算法框架)

(3)、算法框架中定义的方法子类实现相同的使用 private 修饰该方法并且实现,子类实现方法不一样的使用 protected abstact 修饰该方法并且不实现

(4)、让子类重写父类未实现的方法,实现各自的方法

(5)、在调用的实例对象采用 父类 实例名 = new 子类,在直接调用遵循的框架方法


例子1:

/*抽象父类,为所有子类提供一个算法框架
 * step 1: 进门取号
 * step 2: 填写单据
 * step 3: 等待叫号
 * step 4: 窗口办理
 * */
public abstract class Template {

	//定义一个公共 final 的方法(封装所有子类都要遵循的算法框架)
	public final void prepareTemplate()
	{
		//进门取号
		takeNum();
		//填写单据
		writeDoc();
		//等待叫号
		waitCallNum();
		//窗口办理
		handle();
		
		
	}
	
	//算法框架中定义的方法子类实现相同的使用 private 修饰该方法并且实现
	private void takeNum()
	{
		System.out.println("进门取号");
	}
	private void waitCallNum()
	{
		System.out.println("等待叫号");
	}
	//子类实现方法不一样的使用 protected abstact 修饰该方法并且不实现
	protected abstract void writeDoc();
	protected abstract void handle();
	
	
	
}
public class Example extends Template{

	
	
	
	@Override
	protected void writeDoc() {
		// TODO Auto-generated method stub
		System.out.println("填写存款单据");
	}

	@Override
	protected void handle() {
		// TODO Auto-generated method stub
		System.out.println("处理存款");
		
	}

}

public class Example2 extends Template{

	@Override
	protected void writeDoc() {
		// TODO Auto-generated method stub
		System.out.println("填写转账单据");
		
	}

	@Override
	protected void handle() {
		// TODO Auto-generated method stub
		System.out.println("处理转账");
		
	}
	
	

}

测试:

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		
			Template template = new Example();
			template.prepareTemplate();
			System.out.println("-------------------");
			template = new Example2();
			template.prepareTemplate();
			
	}

}

输出结果:

进门取号
填写存款单据
等待叫号
处理存款
-------------------
进门取号
填写转账单据
等待叫号
处理转账


3.可以使用钩子方法使模版方法模式更加灵活

用钩子函数实现子类对算法框架个性化的扩展(简单来说就是通过钩子动态添加步骤)

思想

(1)、框架通过提供一个个的钩子,使框架具备了更大的灵活性。不想执行算法框架中的某些个步骤,我们可以脱钩,如果想执行的话,我们可以挂钩。

实现

(2)、在抽象类中,提供protected钩子方法。这是个实现的或空的方法。这样子类就可以选择覆写-持钩,也可以选择不覆写-脱勾。

使用

(3)、提供一个isXXX类型的钩子方法。用该方法控制算法框架中

某个步骤是否执行

(4)、子类不覆写这个方法,就是脱钩,仍按框架逻辑执行,一旦覆写,就是挂钩,将改变框架算法方向,按子类逻辑执行。

例子2:

/*抽象父类,为所有子类提供一个算法框架
 * step 1: 进门取号
 * step 2: 填写单据
 * step 3: 等待叫号
 * step 4: 窗口办理
 * step 5: 是否需要转到专门窗口办理(根据用户选择)
 * */
public abstract class Template {

	//定义一个公共 final 的方法(封装所有子类都要遵循的算法框架)
	public final void prepareTemplate()
	{
		//进门取号
		takeNum();
		//填写单据
		writeDoc();
		//等待叫号
		waitCallNum();
		//窗口办理
		handle();
		if(isHandleAgain())
		{
			handle();
		}
		
	}
	
	//算法框架中定义的方法子类实现相同的使用 private 修饰该方法并且实现
	private void takeNum()
	{
		System.out.println("进门取号");
	}
	private void waitCallNum()
	{
		System.out.println("等待叫号");
	}
	//子类实现方法不一样的使用 protected abstact 修饰该方法并且不实现
	protected abstract void writeDoc();
	protected abstract void handle();
	
	/*
	 * Hook, 钩子函数,提供一个默认或空的实现
	 * 具体的子类可以自行决定是否挂钩以及如何挂钩
	 * 询问用户是否加入调料
	 */
	 protected boolean isHandleAgain() {
		return false;
	}

	
}


public class Example3 extends Template{

	@Override
	protected void writeDoc() {
		// TODO Auto-generated method stub
		System.out.println("填写单据1,2");
		
	}

	@Override
	protected void handle() {
		// TODO Auto-generated method stub
		System.out.println("处理单据");
		
	}

	//需要挂钩
	@Override
	protected boolean isHandleAgain() {
		// TODO Auto-generated method stub
		return true;
	}
	
	
	
	

}
测试:

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		
			Template template = new Example();
			template.prepareTemplate();
			System.out.println("-------------------");
			template = new Example2();
			template.prepareTemplate();
			System.out.println("-------------------");
			template = new Example3();
			template.prepareTemplate();
	}

}

输出结果:

进门取号
填写存款单据
等待叫号
处理存款
-------------------
进门取号
填写转账单据
等待叫号
处理转账
-------------------
进门取号
填写单据1,2
等待叫号
处理单据
处理单据
5. 总结

模版方法模式

适用场景:

A、算法或者操作遵循相似的逻辑

B、重构时(把相同的代码抽取到父类中)

C、重要、复杂的算法,核心算法设计为模板算法

优点:

A、封装性好

B、复用性好

C、屏蔽细节

D、便于维护


缺点:继承



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值