设计模式心得: 模板方法模式(template method pattern)

很容易理解,将一系列行为封装成一个模板, 这个模板可以被各种具体的行为调用。模板包含的行为可以是通用的, 也可以是根据具体应用有所不同的。当具体应用不同时,行为定义为抽象的,这样在子类中可以自由实现。


例子: 炒菠菜和炒芹菜, 步骤都是: 开火 -> 放油 -> 放菜(不同实现) ->加盐

于是我们有基类:

public abstract class StirFry {
	public void prepareStirFry() {
		openFire();
		addOil();
		addVegetable();
		addSalt();
	}
	public void openFire() {// open fire}
	public void addOil() {//add oil}
	abstract void addVegetable();
	public void addSalt() {//add salt}
}


具体使用时,有两个子类炒菠菜和炒芹菜, 只需事先addVegatable()方法即可,实现了部分解耦:

public class SpinachStirFry extends StirFry {
	pubic void addVegetable() { // add spinach}
}

public class CeleryStirFry extends StirFry {
	public void addVegetable() {// add celery}
}

这样,具体的方法实现就利用了StirFry这个基类模板。


hook:  hook用来自定义如何调用模板方法。 比如在炒菜时,有时需要加辣椒,有时不需要。 一个hook方法:isPepperNeeded() 可以让基类定义一个默认的执行,但是子类可以自定义是否执行此方法。

重写StirFry:

public abstract class StirFry {
	public void prepareStirFry() {
		openFire();
		addOil();
		addVegetable();
		addSalt();
		if (isPepperNeeded()) {
			addPepper();
		}
	}
	public void openFire() {// open fire}
	public void addOil() {//add oil}
	abstract void addVegetable();
	public void addSalt() {//add salt}
	public void addPepper() {//add pepper}
	public boolean isPepperNeeded() {return true;}
}

我们炒菠菜不要辣椒,炒芹菜问用户要不要辣椒。可以这样实现:

public class SpinachStirFry extends StirFry {
	public void addVegetable() { // add spinach}
	@Override
	public boolean isPepperNeeded() {return false;}
}

public class CeleryStirFry extends StirFry {
	public void addVegetable() {// add celery}
	@Override
	public boolean isPepperNeeded() {
		// Ask customer
		// return customer's response
	}
}

在这个例子中,hook方法用来控制需不需要执行某步, hook方法也可以用来控制步骤参数,优先级,等等。


在模板方法模式中,模板的设计是关键。如果太细,则需要太多的钩子方法来控制席位的差别。如果太粗,则大部分方法都要重写,则没有彰显模板方法模式的优越性。


总体来说,模板方法的精髓是: 高级类(StirFry)控制主要步骤,当需要具体化实现时,再询问衍生类。 这样避免了大量无意义的相互方法调用。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值