Template Method模式和Strategy模式:继承与委托

Themeplate Method

 

public abstract class Application {
	protected abstract void init();
	protected abstract void idle();
	protected abstract void cleanup();
	private boolean isDone = false;
	protected void setDone(){
		this.isDone = true;
	}
	protected boolean done(){
		return isDone;
	}
	public void run(){
		init();
		while(!done())
			idle();
		cleanup();
	}
}

 

public class WorkTemplateMethod extends Application {
	public static void main(String[] args){
		new WorkTemplateMethod().run();
	}
	@Override
	protected void cleanup() {
		System.out.println("clean up.");
	}
	@Override
	protected void idle() {
		System.out.println("idle.");setDone();
	}
	@Override
	protected void init() {
		System.out.println("init.");
	}
}

 

Template Method模式展示了面向对象编程中诸多经典重用形式的一种。其中通用算法run()被放置在基类中,并且通过继承在不同的具体上下文中实现该通用算法。

但这项技术也是有代价的。继承是一种非常强的关系,派生类不可避免地要和它们的基类绑定在一起。

如果有个类Application2也需要WorkTemplateMethod中的idle()方法。然而却没法重用,由于继承了Application,就注定把WorkTemplateMethod永远地和Application绑定在了一起。

这时,我们就需要Strategy模式。

Strategy模式

 

public class ApplicationRunner {
	private Application app = null;
	
	public ApplicationRunner(Application app){
		this.app = app;
	}
	public void run(){
		app.init();
		while(!app.done())
			app.idle();
		app.cleanup();
	}
}

 

 

public interface Application {
	public void init();
	public void idle();
	public void cleanup();
	public boolean done();
}

 

 

 

public class WorkStrategy implements Application {
	private boolean isDone = false;

	@Override
	public void cleanup() {
		System.out.println("clean up.");
	}

	@Override
	public boolean done() {
		return isDone;
	}

	@Override
	public void idle() {
		System.out.println("idle.");
		isDone = true;
	}

	@Override
	public void init() {
		System.out.println("init.");
	}

	public static void main(String[] args) {
		new ApplicationRunner(new WorkStrategy()).run();
	}
}

 

WorkStrategy对ApplicationRunner一无所知(main方法作为一个调用的例子,通常它都会在测试类中),它不依赖于run逻辑的任何实现方式。这和TemplateMethod模式是不同的,WorkTemplateMethod完全依赖于它的父类Application中run的逻辑,因而违反了DIP原则,而Strategy方法中不包含这中依赖。因此,当有别的逻辑出现时,也可以复用WorkStrategy实例中的方法。

 

 

public class ApplicationRunner2 {
private Application app = null;
	
	public ApplicationRunner2(Application app){
		this.app = app;
	}
	public void go(){
		//app.init();  不调用init方法
		while(!app.done())
			app.idle();
		app.cleanup();
	}
}

 

 这样,只要使用new ApplicationRunner2(new WorkStrategy()).go()就可以了。

因此,Strategy模式比TemplateMethod模式多推荐了一个额外的好处。尽管TemplateMethod模式允许一个通用算法(run逻辑)操作多个可能的具体实现,但是由于Strategy模式完全遵循DIP原则,从而请允许每个具体实现都可以被多个不两只的通用算法(run逻辑或go逻辑)操纵。

一句话,少用继承,多用接口。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值