博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式之模板方法模式
阅读量:5360 次
发布时间:2019-06-15

本文共 3362 字,大约阅读时间需要 11 分钟。

   模板方法模式定义了一套算法调用步骤的模板,通过继承,子类可以对一个或多个步骤提供实现。当需要扩展时,只需要添加子类即可,而且子类可以复用父类的代码。

 模板方法模式的类图如下:

  

 

 下面以泡茶和冲咖啡为例

  抽象出泡茶和冲咖啡的咖啡因饮料类

/**	定义了模板方法的类,抽象出咖啡和茶的咖啡因饮料类**/public abstract class CaffeineBeverage{	/**		模板方法,调用一系列的步骤,实现制作饮料的步骤	**/	public final void  prepareRecipe()	{		boilWater();		brew();		pourInCup();		if(custormerWantCondiments())		addCondiments();			}	/**		由于把水煮沸的步骤对于任何饮料都是一样的,则父类直接实现该方法	**/	public void boilWater()	{		System.out.println("boil water");	}	public abstract void brew();	public abstract void addCondiments();	public void pourInCup()	{		System.out.println("pour In cup");	}	/**	子类可以选择实现的“钩子”方法	**/	public boolean custormerWantCondiments()	{		return true;	}}

 Tea类

 

/**	继承了模板方法的类Tea,没有实现钩子方法**/public class Tea extends CaffeineBeverage{	public  void brew()	{		System.out.println("Steeping the tea");	}	public void addCondiments()	{			System.out.println("adding lemon");	}	}

 Coffee类

import java.io.*;/**	继承了模板方法的类Coffee类**/public class Coffee extends CaffeineBeverage{	public void brew()	{		System.out.println("Dripping Coffee through filter");	}	public  void addCondiments()	{			System.out.println("adding sugar");	}	/**	子类可以选择实现的“钩子”方法	**/	public boolean custormerWantCondiments()	{			String answer=getUserInput();			if(answer.equals("y"))			{				return true;			}			return false;	}	private String getUserInput()	{		String answer=null;		System.out.println("would you like milk and sugar in your coffee?");		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));		try		{			answer=in.readLine();		}		catch (IOException e)		{			e.printStackTrace();		}		if(answer==null)		{			return "n";		}		return answer;		}}

 测试类

public class Test{	public static void main(String[] args)	{		Coffee coffee=new Coffee();		System.out.println("Making coffee....");		coffee.prepareRecipe();		Tea tea=new Tea();		System.out.println("Making tea....");		tea.prepareRecipe();			}}

 运行结果

 可以看出模板方法定义的步骤里面有三种不同类型的方法:

 1.由父类直接实现的方法:比如上例中的boilWater和pourInCup方法,对于Coffee和Tea来说,都是一样的,所以可以复用,可以定义为final

   2.由子类实现的方法:比如上例中的brew方法

   3.子类可选择实现的方法,比如上例中的customerWantCondiments()方法。

  由模板方法模式中的“钩子”,可以引申出一个设计原则——“好莱坞原则”,“别电话给我,我会打电话给你”,就是说,低层组件可以将自己挂钩到系统上,但是由高层组件决定什么时候和怎样使用这些底层组件,所以对于高层组件来说,其对待低层组件的方式是“别调用我,我会调用你们”。像上例中的customerWantCondiments()方法,就是由子类实现,父类调用。

 模板方法的应用之一是用模板方法排序。

 Arrays类中提供了一个sort方法,sort方法实际上调用了一个私有的mergeSort()方法

 

 mergeSort方法是一个模板方法,我们可以通过改变比较的条件实现自己的排序,我们需要实现的是Comparable接口中的compareTo()方法。

 比如说我们要将学生按成绩排序。

  写一个Student类,实现Comparable接口

public class Student implements Comparable {	public int score;	public String name;	public Student(String name,int score)	{		this.name=name;		this.score=score;	}	public int compareTo(Object object)	{		Student otherStudent=(Student)object;		if(this.score>otherStudent.score)		{			return 1;		}		else if(this.score==otherStudent.score)		{			return 0;		}		else		{			return -1;		}	}}

 测试类

 

import java.util.*;public class TestSort{	public static void main(String[] args)	{		Student[] stu={			new Student("qing",100),			new Student("chen",90),			new Student("zhou",80),			new Student("ddd",50)		};		System.out.println("before sorting....");		display(stu);		System.out.println("after sorting....");		Arrays.sort(stu);		display(stu);		}	public static void display(Student[] stu)	{		for(Student s:stu)		{			System.out.println(s.name+"\t"+s.score);				}	}}

 运行结果是

 

 模板方法模式,策略模式,工厂方法模式的比较

 

转载于:https://www.cnblogs.com/qingfei1994/p/4249862.html

你可能感兴趣的文章
感谢Leslie Ma
查看>>
几种排序方法
查看>>
查看数据库各表的信息
查看>>
第一阶段测试题
查看>>
第二轮冲刺第五天
查看>>
图片压缩
查看>>
Hadoop-2.6.5安装
查看>>
教你如何一步步将项目部署到Github
查看>>
关于Android圆形图片的一种优化方案(可以显示网络图片)
查看>>
Windows路由表详解
查看>>
.NET性能优化方面的总结
查看>>
Windows下文件夹扩展名
查看>>
今天早上6:00起来,每天晚上回来6点多已经天黑
查看>>
debian开启cgroup memory子系统
查看>>
信息收集
查看>>
SQL Server 中使用Convert来取得datetime数据类型样式(全)
查看>>
Python中list的拷贝问题
查看>>
Java学习第二周学习笔记
查看>>
SQL基本语句
查看>>
linux-Centos7安装python3并与python2共存
查看>>