Java大白话介绍~设计模式:模板方法(TemplateMethod)

模板方法设计模式

抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行拓展、改造,但子类总体上会保留抽象类的行为方式。

模板方法解决的问题

当功能内部一部分实现是确定的,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。
换句话说,在软件开发中实现一个算法时,整体的步骤很固定、通用,这些步骤已经在父类中写好了。但是某些部分不确定,不确定的部分可以抽象出来,供不同子类实现。这就是一种模板模式。

代码举例

我们创建一个父类Template,该父类我们创建一个spendTime的方法,想计算出某一段代码的运行时间。整体的步骤就是:
①获取当前的时间
②代码(就是你想测试运行时间的代码)
③获取当前的时间
④两次获取的时间相减,就得出②号代码运行的时间了
但是!问题在于,②号到底要测试什么代码,有好几种情况,我们不确定,可是①②④的步骤我们是百分之一万确定的。所以就将②号需要测试的代码,在父类Template中,给封装成一个抽象方法,让子类去重写,再通过多态来调用。

public class TemplateTest {
	public static void main(String[] args) {
		
		//此处为多态
		Template sub = new SubTemplate();
		sub.spendTime();
		
		//分界线
		System.out.println("**************************");

		//此处为多态
		Template sub_1 = new SubTemplate_1();
		sub_1.spendTime();
	}
}

abstract class Template{
	
	//计算某段代码执行所需要花费的时间
	public void spendTime() {
		//获取当前时间
		long start = System.currentTimeMillis();
		//被测试代码
		code();
		//获取当前时间
		long end = System.currentTimeMillis();
		//输出代码运行时间
		System.out.println("花费的时间为:" + (end - start));
		
	}
	//由于code内具体是什么代码,不确定,此处将其设为抽象方法,交给子类去具体实现
	public abstract void code();
}

class SubTemplate extends Template{
	//重写父类code方法,计算一千以内的质数
	public void code() {
		for(int i = 2;i < 1000;i++	) {
			boolean isFlag = true;
			for(int j = 2;j < Math.sqrt(i);j++) {
				if(i % j == 0) {
					isFlag = false;
					break;
				}
			}
			if(isFlag) {
				System.out.println(i);
			}
		}
	}
}
class SubTemplate_1 extends Template{
	//重写父类code方法,计算五百以内的质数
	public void code() {
		for(int i = 2;i < 500;i++	) {
			boolean isFlag = true;
			for(int j = 2;j < Math.sqrt(i);j++) {
				if(i % j == 0) {
					isFlag = false;
					break;
				}
			}
			if(isFlag) {
				System.out.println(i);
			}
		}
	}
}

一句话概括设计模式:模板方法

父类Template就是一个模板,这个模板单独拿出来没有任何意义,只有根据不同的情况去实例化不同的子类,子类重写父类的空白的抽象方法,两者结合,才有了意义。

总结

由上述代码可以总结,我们不确定要测试哪段代码的执行时间,我们就在父类中创建一个抽象方法,然后在子类中去具体实现该方法,然后通过多态来实现访问子类中被重写的方法,就可以实现测试不同的代码运行的时间。
此处只是举了一个简单的例子,模板方法还有很多用途。

读者可能存在的疑惑

①父类中的public abstract void code();为什么要声明为抽象的,不声明抽象,我子类也可以重写该方法,实现相同的效果。
答:如果父类该方法不声明为抽象方法,该方法就得写成public void code(){ },并且存在万一子类没有重写code方法,然后你又调用了spendTime()方法,那么这样子做毫无意义。此处将其声明为抽象方法,就会强制要求你子类中必须重写code方法,尽量的减少了调用了一个空的方法体的可能,如果你子类重写还是重写空的方法体,那这样子做也没意义呀。

②父类Template和子类code都不声明为抽象,也可以实现上述情况代码
答:此处回答同上,如果父类Template和子类code都不是抽象的,那么就可以直接创建一个父类的实例,调用里面的方法,但是code方法又是空的,这样子做毫无意义,声明为抽象就是不希望你们创建父类的实例,父类仅仅就是作为一个模板而存在。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值