文档章节

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

文森特梵高
 文森特梵高
发布于 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
广州
程序员
Java 设计模式(14) —— 复合模式

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

磊_lei
05/26
0
0
设计模式15——Template Method设计模式

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

小米米儿小
2014/01/24
0
0
(目录)设计模式(可复用面向对象软件的基础)

本系列“设计模式”博客使用Golang语言实现算法。所谓算法是指解决一个问题的步骤,个人觉得不在于语言。小弟只是最近学习Golang,所以顺带熟练一下语法知识,别无它意。 本系列博客主要介绍...

chapin
2015/01/13
0
0
编程中的那些经典套路——设计模式汇总

在正式阅读前,我先谈谈我们该用什么姿势和心态学习设计模式: 如果你还没有过多的编程经验(泛指半年以下),我建议你把它当做小说来看,能看懂多少是多少,因为半年以下经验的程序员用到设...

gzchen
08/27
0
0
【设计模式笔记】(十六)- 代理模式

一、简述 代理模式(Proxy Pattern),为其他对象提供一个代理,并由代理对象控制原有对象的引用;也称为委托模式。 其实代理模式无论是在日常开发还是设计模式中,基本随处可见,中介者模式中...

MrTrying
06/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

创建第一个react项目

sudo npm i -g create-react-app@1.5.2 create-react-app react-app cd react-apprm -rf package-lock.jsonrm -rf node_modules #主要是为了避免报错npm installnpm start......

lilugirl
今天
1
0
在浏览器中进行深度学习:TensorFlow.js (八)生成对抗网络 (GAN)

Generative Adversarial Network 是深度学习中非常有趣的一种方法。GAN最早源自Ian Goodfellow的这篇论文。LeCun对GAN给出了极高的评价: “There are many interesting recent development...

naughty
今天
0
0
搬瓦工镜像站bwh1.net被DNS污染,国内打不开搬瓦工官网

今天下午(2018年10月17日),继搬瓦工主域名bandwagonhost.com被污染后,这个国内的镜像地址bwh1.net也被墙了。那么目前应该怎么访问搬瓦工官网呢? 消息来源:搬瓦工优惠网->搬瓦工镜像站b...

flyzy2005
今天
3
0
SpringBoot自动配置

本篇介绍下,如何通过springboot的自动配置,将公司项目内的依赖jar,不需要扫描路径,依赖jar的情况下,就能将jar内配置了@configuration注解的类,创建到IOC里面 介绍下开发环境 JDK版本1.8 spr...

贺小五
今天
3
0
命令行新建Maven多项目

参考地址 # DgroupId 可以理解为包名# DartifactId 可以理解为项目名mvn archetype:generate -DgroupId=cn.modfun -DartifactId=scaffold -DarchetypeArtifactId=maven-archetype-quickst......

阿白
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部