文档章节

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

文森特梵高
 文森特梵高
发布于 2015/08/14 09:47
字数 968
阅读 48
收藏 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
0
0
《JavaScript设计模式与开发实践》模式篇(12)—— 装饰者模式

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

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

没有更多内容

加载失败,请刷新页面

加载更多

jenkins 配置

1. ssh-keygen -t rsa 2. 配置 GitLab 用户 创建一个用户或选择一个已有用户,用来让 Jenkins 和 GitLab API 交互。这个用户将需要是全局的管理员或添加进每个组/工程,并作为成员。需要开发...

关上越
16分钟前
1
0
中台迷思

到处都在喊中台,到处都是中台,中台这个词在我看来已经被滥用了。 在有些人眼里:中台就是技术平台,像微服务开发框架、Devops平台、PaaS平台,容器云之类的,人们都叫它“技术中台”。 在有...

老道士
23分钟前
2
0
Linux命令参数解析

Linux命令参数 通过一个例子来理解什么是Linux命令参数。以Linux中常用的删除命令“rm”为例,输入“rm --help”可以看到如下信息,其中红色框内的就是命令参数。经常使用Linux对命令参数应该...

RongJinhui0
26分钟前
1
0
边缘节点服务ENS重磅升级 阿里云首次定义“边缘云计算”概念层层深入

摘要: 在这一横一纵之间,阿里云在2018年率先提供了基于运营商边缘节点和网络的弹性分布式算力资源平台,也就是边缘节点服务ENS,连接最后10公里的ENS可以帮助用户将计算、转发等业务下沉至...

阿里云云栖社区
31分钟前
2
0
阿里云 Aliplayer高级功能介绍(四):直播时移

基本介绍 时移直播基于常规的HLS视频直播,直播推流被切分成TS分片,通过HLS协议向播放用户分发,用户请求的m3u8播放文件中包含不断刷新的TS分片地址;对于常规的HLS直播而言,TS分片地址及相...

阿里云官方博客
34分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部