关于Template Method模式——软件构造

  • Post author:
  • Post category:其他


1.前情提要

在哈尔滨工业大学软构造的期末考试中,有一道有关模板模式的题目。题目内容如下:

某ADT的功能是随机选择诗中的若干行,以日志形式输出文本,其代码如下所示。

class Recorder{
	private static final NUMBER = 5; //随机选择的次数
	private static final Logger log = Logger.getLogger("Recorder");
	private Poem poem;
	
	public void recording(){
	poem = new Poem(...); //此处忽略了参数,新建一个poem对象
	log.addHandler(new ConsoleHandler());
	log.setLevel(Level.INFO);
	
	Random r = new Random();
	List<String> lines = poem.getAllLines();
	for(int i = 0;  i < NUMBER; i++){
		String line = lines.get(r.nextInt(lines.size()));
		if(line.length() >= 10) //长度超过10才可被日志输出
			log.info(line);
		}
	}
}

后续要扩展新功能;在不同场景下,诗歌对象(poem)可从不同的源头读入(例如磁盘文件、用户键盘输入、某网络地址等)而不只是在方法中新创建;输出日志的渠道可从控制台输出扩展到其他输出(例如写入磁盘文件、写入某个网络地址等);随机选择诗歌文本行的时候,文本行的长度限制也可自由配置(而不是目前局限于10)。

请使用template method设计模式,对上述代码进行改造,以支持上述功能扩展。写出你进行代码改造的基本思路描述,无需写出具体代码。

上面就是题目内容了。可以看到题目的关键便是这个“template method”,所以要做这道题首先就要知道什么是template method。可以说我就不是很理解什么是template method,所以想重新复习一下关于template method(虽然考试已经结束了),并且重新做一下这道题。

2.什么是template method。

Template method翻译过来就是模板模式。其主要思想就是公共的部分在抽象类中实现,不同的部分在子类中具体实现。就好像是抽象类创建了一个模板,用不同的方法来实现这个模板,所以命名为模板模式。

举个例子,某个快餐店可以制作两种汉堡:至尊牛肉堡和照烧鸡腿堡。这两种汉堡制作过程相似,但是具体步骤又有些不同。就很适合使用模板模式来完成制作过程。

首先是建立一个抽象类

abstract class MakingBurgers{
	final void MakingBurgers(){
		heatBread();
		addMeat();
		addVagetable();
		addSauce();
	}
	
	//加热面包的过程相同
	void heatBread(){
		System.out.println("加热面包")}
	
	//两种汉堡的制作过程相似但不相同
	abstract void addMeat();
	abstract void addVagetable();
	abstract void addSauce();
}

两种汉堡不同的部分在子类中具体实现。

class BeefBurgers extends MakingBurgers{
	public void addMeat(){
		System.out.println("加入牛肉饼");
	}

	public void addVagetable(){
		System.out.println("加入酸黄瓜和番茄");
	}

	public void addSauce(){
		System.out.println("加入蛋黄酱");
	}
}
class ChickenBurgers extends MakingBurgers{
	public void addMeat(){
	  	System.out.println("加入鸡腿肉");
	}

	public void addVagetable(){
		System.out.println("加入生菜");
	}

	public void addSauce(){
		System.out.println("加入照烧酱");
	}
}

3.重新考虑考试题

首先,应该建立一个抽象类,在这个类中,输入和输出应该以抽象方式出现。而随机选择诗中的若干行这一功能可以具体实现,因为这个步骤是所有子类都会用到的,同时也都完全相同的。

其次,在选择过程中,应该用一个变量存储题目中的文本行的长度限制量(本题为10),尽量避免程序出现幻数是程序员的基本素养,同时也满足了题目中可以对文本行的长度限制自由配置的要求。

最后,用具体的子类来实现输入输出的部分,比如磁盘子类就是用磁盘读入和写入磁盘文件来完成输入和输出功能,网络子类就是用网络地址来完成输入和输出功能。

但是,上述的思路其实还有些缺陷,假如我想用磁盘读入文件,然后将它输入到控制台上,就需要单独设计一个子类,这样就会产生很多子类。所以感觉这个方法还不是很完美。但是我还没有想到更好的实现思路,如果之后有更好的思路,再来进行补充吧。



版权声明:本文为v5_otto原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。