设计模式笔记—模板方法模式

      概念

         定义一个操作中的算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

        使用场景

         1)多个子类有公有的方法,并且逻辑基本相同时。
         2)重要,复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现。
         3)重构时,模板方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过钩子函数约束其行为。
         抽象模板的方法分两类:
                1)基本方法:也叫基本操作,是由子类实现的方法,并且在模板方法被调用。
                2)模板方法:可以有个或几个,一般是一个具体方法,也就是一个框架,实现对基本方法的调度,完成固定的逻辑。如下:
//抽象模板类
public abstract class AbstractClass {
	//基本方法
	protected abstract void doSomething(); 
	//基本方法
	protected abstract void doAnything();
	//模板方法
	public void templateMethod(){
		//调用基本方法,完成相关的逻辑
		this.doAnything();
		this.doSomething();
	}
}
      举例:设计汽车
//抽象模板类
public abstract class HummerModel {
	//开车
	protected abstract void start();
	//停车
	protected abstract void stop();
	//出喇叭声音
	protected abstract void  alarm();
	//发出引擎声
	protected abstract void engineBoom();
	
	final public void run(){
		this.start();
		this.engineBoom();
		if(this.isAlarm()){
			this.alarm();
		}
		this.stop();
	}
	//钩子方法,默认喇叭是会响的
	protected boolean isAlarm(){
		return true;
	}
}
public class HummerH1 extends HummerModel{
	private boolean alarmFlag=true;//要响喇叭
	@Override
	protected void start() {
		System.out.println("悍马H1发动");
	}
	@Override
	protected void stop() {
		System.out.println("悍马H1停车");
	}
	@Override
	protected void alarm() {
		System.out.println("悍马H1鸣笛");
	}
	@Override
	protected void engineBoom() {
		System.out.println("悍马H1引擎声音...");
	}
	protected boolean isAlarm(){
		return this.alarmFlag;
	}
	//要不要响喇叭,由客户来决定的
	public void setAlarm(boolean isAlarm) {
		this.alarmFlag = isAlarm;
	}
}
public class HummerH2 extends HummerModel{
	@Override
	protected void start() {
		System.out.println("悍马H2发动");
	}
	@Override
	protected void stop() {
		System.out.println("悍马H2停车");
	}
	@Override
	protected void alarm() {
		System.out.println("悍马H2鸣笛");
	}
	@Override
	protected void engineBoom() {
		System.out.println("悍马H2引擎声音...");
	}
	@Override
	protected boolean isAlarm() {
		return false;
	}
}
//测试
public class Client {
public static void main(String[] args) throws IOException {
	System.out.println("H1型号是否需要喇叭声响?0-不需要  1-需要");
	String type=(new BufferedReader(new InputStreamReader(System.in))).readLine();
	HummerH1 h1 = new HummerH1();
	if(type.equals("0")){
		h1.setAlarm(false);
	}
	h1.run();
	System.out.println("\n------H2型号--------");
	HummerH2 h2 = new HummerH2();
	h2.run();
}
}
测试结果:
H1型号是否需要喇叭声响?0-不需要  1-需要
1
悍马H1发动
悍马H1引擎声音...
悍马H1鸣笛
悍马H1停车

------H2型号--------
悍马H2发动
悍马H2引擎声音...
悍马H2停车
H1型号是否需要喇叭声响?0-不需要  1-需要
0
悍马H1发动
悍马H1引擎声音...
悍马H1停车

------H2型号--------
悍马H2发动
悍马H2引擎声音...
悍马H2停车

        分析:H1型号汽车是由客户控制是否要想鸣笛,也就是说外界条件改变,影响到模板方法的执行。抽象类中isAlarm的返回值就是影响模板方法的执行结果,这个方法也叫钩子方法。

         模板模式的优缺点

          优点:1 封装不变部分,扩展可变部分. 2 提取公共部分代码,便于维护. 3 行为由父类控制,子类实现.
          缺点:模板方法会带来代码阅读的难度,会让用户觉得难以理解。




 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值