文档章节

五、设计模式——模板模式

文森特梵高
 文森特梵高
发布于 2015/08/14 09:47
字数 968
阅读 50
收藏 1

如何泡咖啡和泡茶?

思考,变化与不变?

很显然,变化的是咖啡喝茶,而泡的步骤没有改变。

第一个层次的抽象,就是讲公共的步骤放在超类中,比如“水烧开”、“倒入杯子”

public abstract class HotDrink {
	public abstract void prepareRecipe();
	public void boilWater() {
		System.out.println("Boiling water");
	}
	public void pourInCup() {
		System.out.println("Pouring into cup");
	}
}


我们发现,除了上述两个步骤一样之外,“冲泡”和“加入材料”这两个动作本质也是一样的。

因此我们总结出第二个层次的抽象。

public abstract class HotDrink {
	public final void prepareRecipe() {//因为步骤也是一样的,所以固定化
		boilWater();
		brew();
		pourInCup();
		addCondiments();
	}
	public abstract void brew();//因为冲泡和加的辅料不同,因此抽象
	public abstract void addCondiments();
	public final void boilWater() {//完全一样的,直接在超类中实现
		System.out.println("Boiling water");
	}
	public final void pourInCup() {
		System.out.println("Pouring into cup");
	}
}

public class Coffee extends HotDrink {

	@Override
	public void brew() {
		System.out.println("Brewing Coffee");
	}

	@Override
	public void addCondiments() {
		System.out.println("Adding sugar and milk");
	}

}


模板模式:

封装了一个算法步骤,允许之类为一个或多个步骤提供实现。模板模式允许之类在不改变算法结构的情况下,重新定义算法的某些步骤。



通过hook增加模板方法的实用性


思考,上述中的算法步骤都写死了,那么不就对扩展不利吗?假设某些步骤在某些情况下可以不执行,如何实现?

针对这个问题,其实模板模式提供了钩子的概念,之类可以通过钩子来影响模板方法中的某些步骤,达到灵活执行的目的。

public abstract class HotDrink {

	public final void prepareRecipe() {
		boilWater();
		brew();
		pourInCup();
		if (wantCondimentsHook())
			addCondiments();
		else
			System.out.println("No need to add condiments");
	}
	
	public abstract void brew();
	
	public abstract void addCondiments();
	
	public boolean wantCondimentsHook() {
		return true;
	}
	
	public final void boilWater() {
		System.out.println("Boiling water");
	}
	
	public final void pourInCup() {
		System.out.println("Pouring into cup");
	}
}

public class Coffee extends HotDrink {

	@Override
	public void brew() {
		System.out.println("Brewing Coffee");
	}

	@Override
	public void addCondiments() {
		System.out.println("Adding sugar and milk");
	}

	@Override
	public boolean wantCondimentsHook() {
		return false;
	}
}




身边的模板模式


Array.sort()方法就是一个模板模式的运用,不同是Java将抽象方法移动到对象上。对象需要实现Comparable接口。

public abstract class SortTemplate {

	public final void sort(Object[] objects) {
		for (int i = 0; i < objects.length - 1; i++) {
			if (compare(objects[i+1]) > 0) {
				//swap();
			} else {
				
			}
		}
	}
	
	public abstract int compare(Object object);
}


Android中的组件,BaseAdapter其实也是模板模式。

public class MyAdapter extends BaseAdapter {
    public MyAdapter(Context ctx) {
        this.ctx = ctx;
    }
    //...略...
    @Override
    public int getCount() {
        return data.length;
    }
    @Override
    public int Object getItem(int arg0) {
        return data.get(arg0);
    }
    @Override
    public View getView(int position , int convertView , ViewGroup arg2) {
        //...略...
        return view;
    }
    //...略...
}

上述提供的函数,都是模板方法的步骤调用的。因此来获知空间的元素数量,在显示的时候会调用getView函数。


Activity的生命周期,onStart()、onCreate()、onStop()、onDestroy()等函数,也是模板方法模式的应用。



好莱坞原则


好莱坞原则:别调用我们,我们调用你。

好莱坞原则就是经纪人和明星之间的关系,经纪人负责安排明星的时间表,明星只需要根据经纪人的安排把活动做好,把歌长号,参加粉丝见面会,等等就好了。

在系统中,有一个专门的部分负责流程,而其他部分只需要将流程中的各个步骤做好即可,这样可以很好的解耦,模块之间西相互独立。



模板模式和策略模式 的 差异


模板模式是对流程和步骤的封装,而且是通过继承的方式实现。

策略模式是在超类中将动作进行抽象,通过让不同的方法族能够相互替代,通过组合的方式实现。

策略模式可以与模板模式结合使用,结合点在于模板模式的abstract方法改成引用接口,之类通过传入不同的接口实例达到解耦的目的。

© 著作权归作者所有

文森特梵高
粉丝 2
博文 28
码字总数 15386
作品 0
广州
程序员
私信 提问
《JavaScript设计模式与开发实践》最全知识点汇总大全

系列文章: 《JavaScript设计模式与开发实践》基础篇(1)—— this、call 和 apply 《JavaScript设计模式与开发实践》基础篇(2)—— 闭包和高阶函数 《JavaScript设计模式与开发实践》模式...

嗨呀豆豆呢
01/04
0
0
Java 设计模式(14) —— 复合模式

一、复合模式 模式常一起使用,组合在一个设计解决方案中 复合模式在一个解决方案中结合两个或多个模式,能解决一般性或一系列的问题 二、示例 本次设计模式讲解中无代码示例,由于复合模式是...

磊_lei
2018/05/26
0
0
《JavaScript设计模式与开发实践》原则篇(2)—— 最少知识原则

最少知识原则(LKP)说的是一个软件实体应当尽可能少地与其他实体发生相互作用。这 里的软件实体是一个广义的概念,不仅包括对象,还包括系统、类、模块、函数、变量等。 单一职责原则指导我们...

嗨呀豆豆呢
2018/12/30
0
0
设计模式15——Template Method设计模式

Template Method模板方法设计模式定义一个操作中算法的骨架,将具体步骤的执行延迟到子类中实现。Java中的抽象类就是使用了模板方法设计模式。模板方法设计模式结构如下: 以文档处理为例,T...

小米米儿小
2014/01/24
218
0
《JavaScript设计模式与开发实践》模式篇(12)—— 装饰者模式

在传统的面向对象语言中,给对象添加功能常常使用继承的方式,但是继承的方式并不灵活, 还会带来许多问题:一方面会导致超类和子类之间存在强耦合性,当超类改变时,子类也会随之 改变;另一方...

嗨呀豆豆呢
2018/12/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

好程序员web前端教程分享web前端入门基础知识

  好程序员web前端教程分享web前端入门基础知识,作为合格的Web前端工程师必须得掌握HTML、CSS和JavaScript。只懂其中一两个还不行,必须对这三门语言都要熟悉。下面我们一起来看一看吧! ...

好程序员官网
13分钟前
3
0
elasticsearch 中文分词插件IK-Analyze

elasticsearch 版本 7.3 安装中文分词插件 插件对应的版本需要和elasticsearch的版本一致 插件各个版本下载地址 https://github.com/medcl/elasticsearch-analysis-ik/releases 使用elastic...

kdy1994
17分钟前
3
0
只用一套解决方案,就可解决80%的交通物流行业信息难题

行业背景 新中国成立70多年来,中国交通运输总体上已经形成了多节点、全覆盖的综合运输网络,“五纵五横”综合运输大通道基本贯通,一大批综合客运、货运枢纽站场(物流园区)投入运营,取得...

朕想上头条
19分钟前
4
0
spring-boot结合AOP实现数据源动态配置

Spring-Boot+AOP方式实现多数据源切换 设计总体思路:Spring-Boot+AOP方式实现多数据源切换,继承AbstractRoutingDataSource实现数据源动态的获取,在service层使用注解指定数据源。 一、多数...

蜗牛伊
20分钟前
3
0
干货 | 京东技术中台的Flutter实践之路

在 2019 年,Flutter 推出了多个正式版本,支持的终端越来越多,使用的项目也越来越多。Flutter 正在经历从小范围尝鲜到大面积应用的过程,越来越多的研发团队加入到 Flutter 的学习热潮中,...

京东云技术新知
23分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部