模板方法模式初学和实例练习(包括钩子方法应用)

模板方法模式

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
模板方法模式适用的设计场景
设计者需要给出一个算法的固定步骤,并将某些步骤的具体实现留给子类来实现。
需要对代码进行重构,将各个子类公共行为提取出来集中到一个共同的父类中以避免代码重复。
模板方法模式的优点
可以通过在抽象模板定义模板方法给出成熟的算法步骤,同时又不限制步骤的细节,具体模板实现算法细节不会改变整个算法的骨架。
在抽象模板模式中,可以通过钩子方法对某些步骤进行挂钩,具体模板通过钩子可以选择算法骨架中的某些步骤。
两个角色
抽象模板(抽象方法、具体方法、模板方法、钩子方法)、具体模板
在这里插入图片描述

实例练习

1、显示某个目录下全部文件的名字,比如可以按文件的大小顺序,按最后修改的时间顺序或按文件名字的字典顺序来显示某个目录下全部文件的名字

1)抽象模板
AbstractTemplate.java

package mbffms_1;
import java.io.*;
public abstract class AbstractTemplate {
	//抽象模板
	File[] allFiles;
	File dir;
	AbstractTemplate(File dir){
		this.dir=dir;
	}
	public final void showFileName() {//模板方法
		allFiles=dir.listFiles();
		sort();
		printFiles();
	}
	public abstract void sort();
	public abstract void printFiles();
}

2)具体模板
ConcreteTemplate1.java

package mbffms_1;
import java.io.*;
import java.awt.*;
import java.util.Date;
import java.text.SimpleDateFormat;
public class  extends AbstractTemplate{
	//具体模板
	ConcreteTemplate1(File dir) {
		super(dir);
	}
	public void sort() {
		for(int i=0;i<allFiles.length;i++)
			for(int j=i+1;j<allFiles.length;j++)
				if(allFiles[j].lastModified()<allFiles[i].lastModified()) {
					File file=allFiles[j];
					allFiles[j]=allFiles[i];
					allFiles[i]=file;
				}
	}
	public void printFiles() {
		for(int i=0;i<allFiles.length;i++) {
			long time=allFiles[i].lastModified();
			Date date=new Date(time);
			SimpleDateFormat matter=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String str=matter.format(date);
			String name=allFiles[i].getName();
			int k=i+1;
			System.out.println(k+" "+name+"("+str+")");
		}
	}
}

ConcreteTemplate2.java

package mbffms_1;
import java.io.*;
import java.awt.*;
import java.util.Date;
import java.text.SimpleDateFormat;
public class ConcreteTemplate2 extends AbstractTemplate{
	//具体模板
	ConcreteTemplate2(File dir) {
		super(dir);
	}
	public void sort() {
		for(int i=0;i<allFiles.length;i++)
			for(int j=i+1;j<allFiles.length;j++)
				if(allFiles[j].lastModified()<allFiles[i].lastModified()) {
					File file=allFiles[j];
					allFiles[j]=allFiles[i];
					allFiles[i]=file;
				}
	}
	public void printFiles() {
		for(int i=0;i<allFiles.length;i++) {
			long fileSize=allFiles[i].length();
			String name=allFiles[i].getName();
			int k=i+1;
			System.out.println(k+" "+name+"("+fileSize+"字节)");
		}
	}
}

3)测试类

package mbffms_1;
import java.io.File;

public class test {
	public static void main(String[] args) {
		//自己选择文件目录
		File dir=new File("e:/面向对象程序设计/面B");
		AbstractTemplate template=new ConcreteTemplate1(dir);
		System.out.println(dir.getPath()+"目录下的文件:");
		template.showFileName();
		template=new ConcreteTemplate2(dir);
		System.out.println(dir.getPath()+"目录下的文件:");
		template.showFileName();
	}
}

2、钩子方法运用

钩子方法是抽象模板中定义的具体方法,但给出了空实现或默认的实现,并允许子类重写这个具体方法,允许具体模板对算法的不同点进行挂钩,以确定在什么条件下执行模板方法中的哪些算法步骤,干扰父类算法进程
比如说有一个接口,这个接口里有3个方法,而你只想用其中一个方法,那么这时,你可以写一个抽象类实现这个接口,在这个抽象类里将你要用的那个方法设置为abstract,其它方法进行空实现,然后再继承这个抽象类,就不需要实现其它不用的方法,这就是钩子方法的作用。

单词排序显示案例

统计英文文本文件中单词的步骤:
①标题读取文件的内容。
②标题统计出文件内容中的全部单词。
③标题将单词按着某种顺序排序,比如,按字典顺序或单词的长度排序单词,但允许具体模板对排序挂钩,即具体模板可以对单词排序也可以不对单词进行排序。
④标题输出全部的单词。
抽象模板
WordsTemplate.java

package mbffms_2;
import java.io.*;
public abstract class  {
	File file;
	String content;
	String[] word;
	WordsTemplate(File file){
		this.file=file;
		content="";
	}
	public final void showAllWords() {//模板方法
		readContent();
		getWords();
		if(isSort())   //挂钩处
			sort(word);
		printWords(word);
	}
	public void readContent() {
		try {
			StringBuffer str=new StringBuffer();
			FileReader inOne=new FileReader(file);
			BufferedReader inTwo=new BufferedReader(inOne);
			String s=null;
			while((s=inTwo.readLine())!=null)
				str.append(s+"\n");
			content=new String(str);
			inOne.close();
			inTwo.close();
		}
		catch(IOException exp) {}
	}
	public final void getWords() {
		//空格字符、数字和符号组成的正则表达式
		String regex="[\\s\\d\\p{Punct}]+";
		word=content.split(regex);
	}
	public boolean isSort() {//钩子方法
		return true;
	}
	public void sort(String[] word) {}   //钩子方法
	public final void printWords(String[] word) {
		int j=0;
		for(int i=0;i<word.length;i++) {
			System.out.printf("%-10s",word[i]);
			//每7个单词换一行输出
			j++;
			if(j>6) {
				System.out.println();
				j=0;
			}
		}
		System.out.println();
	}
}

具体模板
WordSortTemplate.java

package mbffms_2;
import java.io.*;
import java.util.*;

public class WordSortTemplate extends WordsTemplate{
	WordSortTemplate(File file) {
		super(file);
	}
	public void sort(String[] word) {
		Arrays.sort(word);
	}
}

WordNoSortTemplate.java

package mbffms_2;
import java.io.*;
import java.util.*;

public class WordNoSortTemplate extends WordsTemplate{
	WordNoSortTemplate(File file) {
		super(file);
	}
	public boolean isSort() {
		return false;
	}
}

测试类

package mbffms_2;
import java.io.File;

public class test {
	public static void main(String[] args) {
		//注意文件存放的位置,位于java项目文件夹中
		File file=new File("test.txt");
		WordsTemplate template=new WordSortTemplate(file);
		//按字典顺序大写字母在小写字母之前
		System.out.println(file.getName()+"中有如下的单词(按字典顺序):");
		template.showAllWords();
		template=new WordNoSortTemplate(file);
		System.out.println(file.getName()+"中有如下的单词(按文中出现的先后顺序):");
		template.showAllWords();
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值