Java设计模式之模板方法模式

模板方法模式(Template Pattern)是设计模式里面非常简单的一种设计模式,在学习模板方法模式之前,我不知道什么模板方法模式,学了之后才知道原来我一直有在用这个模式。模板方法模式是一个抽象类公开定义了执行它的方法的方式/模板,属于行为型模式。

(行为模式:中介者模式、命令模式、备忘录模式、状态模式、策略模式、解释器模式、迭代器模式、观察者模式、访问者模式、模板方法模式)

 

定义:

Define the skeleton of an algorithm in an operation,deferring some steps to subclasses.Template

Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's

structure.

定义一个操作中的算法的框架, 而将一些步骤延迟到子类中。 使得子类可以不改

变一个算法的结构即可重定义该算法的某些特定步骤。

 

类图:

 

抽象模板类中一般有两种方法,基本方法和模板方法。

基本方法:一种具体的操作,由模板方法调用,由子类实现方法。如上图中的,doAnything和doSomething。

模板方法:实现某种算法的方法步骤,可以一个也可以是多个。如上图中的templateMethod。

 

基本方法里面有一种比较特别的方法叫钩子方法,钩子方法由一个抽象类或具体类声明并实现,而其子类可能会加以扩展。

 

优点:

封装不变部分, 扩展可变部分。

提取公共部分代码, 便于维护。

行为由父类控制, 子类实现。

缺点:

每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。

 

应用场景:

多个子类有公有的方法, 并且逻辑基本相同时。

重要、 复杂的算法, 可以把核心算法设计为模板方法, 周边的相关细节功能则由各个

子类实现。

重构时, 模板方法模式是一个经常使用的模式, 把相同的代码抽取到父类中, 然后通

过钩子方法约束其行为。

 

概念看起来很简单,实际理解来还不是很直观,我们就来举个例子说明一下。

 

我就拿制造汽车来举个例子吧,由于本人不是很清楚汽车是怎么制造的,就虚构一个流程,能看到就好。

 

制造汽车抽象模板类

package org.clarezhou.designpattern.templatepattern;

/**
 * 生产汽车(以下生产汽车过程纯属虚构,切勿当真)
 * @author clarezhou
 *
 */
public abstract class BuildCarsTemplate {
	
	//制造车的支架
	protected abstract void buildKickstand();
	
	//制造发动机
	protected abstract void buildEngine();
	
	//制造各种零件
	protected abstract void buildComponent();
	
	//组装
	protected abstract void assemble();
	
	//生成汽车
	final public void product(){
		//先制造汽车的整体支架
		this.buildKickstand();
		//制造发动机等等
		this.buildEngine();
		//制造各种零件
		this.buildComponent();
		//组装汽车
		this.assemble();
		//汽车制造就这么完成了。
	}
}

 

具体模板类,制造宝马车

package org.clarezhou.designpattern.templatepattern;

/**
 * 制造宝马车
 * @author clarezhou
 *
 */
public class BMWCar extends BuildCarsTemplate{

	@Override
	protected void buildKickstand() {
		System.out.println("生产宝马车支架");
	}

	@Override
	protected void buildEngine() {
		System.out.println("生产宝马车发动机等");
	}

	@Override
	protected void buildComponent() {
		System.out.println("生产宝马车零件");
	}

	@Override
	protected void assemble() {
		System.out.println("组装宝马车,宝马车制造完成");
	}
}

 

奔驰车

package org.clarezhou.designpattern.templatepattern;

/**
 * 制造奔驰汽车
 * @author clarezhou
 *
 */
public class BenzCar extends BuildCarsTemplate{

	@Override
	protected void buildKickstand() {
		System.out.println("制造奔驰汽车支架");
	}

	@Override
	protected void buildEngine() {
		System.out.println("制造奔驰发动机");
	}

	@Override
	protected void buildComponent() {
		System.out.println("制造奔驰各种零件");
	}

	@Override
	protected void assemble() {
		System.out.println("组装奔驰汽车,奔驰汽车制造完成");
	}
}

 

制造汽车场景类

package org.clarezhou.designpattern.templatepattern;

/**
 * 造车
 * @author clarezhou
 *
 */
public class BuildCar {
	
	public static void main(String[] args) {
		BuildCarsTemplate bmwcar = new BMWCar();
		BuildCarsTemplate benzCar = new BenzCar();
		
		bmwcar.product();
		benzCar.product();
	}
}

运行结果:

 

如果这时候,我们想做一个玩具车,并不需要发动机,但又想继续使用这个模板该怎么改呢。

抽象模板类

package org.clarezhou.designpattern.templatepattern;

/**
 * 生产汽车(以下生产汽车过程纯属虚构,切勿当真)
 * @author clarezhou
 *
 */
public abstract class BuildCarsTemplate {
	
	//制造车的支架
	protected abstract void buildKickstand();
	
	//制造发动机
	protected abstract void buildEngine();
	
	//制造各种零件
	protected abstract void buildComponent();
	
	//组装
	protected abstract void assemble();
	
	// 钩子方法 是否需要发动机
	protected boolean isEngine(){
		return true;
	}
	
	//生成汽车
	final public void product(){
		//先制造汽车的整体支架
		this.buildKickstand();
		if(this.isEngine()){
			//制造发动机等等
			this.buildEngine();
		}
		//制造各种零件
		this.buildComponent();
		//组装汽车
		this.assemble();
		//汽车制造就这么完成了。
	}
}

 

玩具车

package org.clarezhou.designpattern.templatepattern;

/**
 * 玩具车 不需要发动机
 * @author clarezhou
 *
 */
public class ToyCar extends BuildCarsTemplate{

	private boolean flag = false;//不需要引擎
	
	@Override
	protected void buildKickstand() {
		System.out.println("制造玩具车支架");
	}

	@Override
	protected void buildEngine() {
		System.out.println("制造玩具车引擎");
	}

	@Override
	protected void buildComponent() {
		System.out.println("制造玩具车零件");
	}

	@Override
	protected void assemble() {
		System.out.println("组装玩具车");
	}
	
	protected boolean isEngine(){
		return this.flag;
	}
}

 

 运行结果:

 

模板方法模式是不是很简单,还非常的好用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值