设计模式之禅-模板方法模式

个人Blog 此篇博文所在地址:http://www.sanyinchenblog.com/?p=273

模板方法模式:

定义一个操作中的算法框架,将一些步骤延迟到子类中。使得子类可以不改变    一个算法的结构即可重定义该算法的某些特定步骤。

Demo:

https://github.com/sanyinchen/UMLDemo/tree/master/src/com/sanyinchen/templete

https://github.com/sanyinchen/UMLDemo/tree/master/src/com/sanyinchen/templete2

介绍一下书上的背景,大概的背景是要做一个车的模型。

类图是这样的:

Client类:

package com.sanyinchen.templete;

public class Client {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		HummerModel hummerModel = new HummerH1Model1();
		hummerModel.start();
		hummerModel.engineBoom();
		hummerModel.alarm();
		hummerModel.run();
		System.out.println("--------------------");
		hummerModel = new HummerH1Model2();
		hummerModel.start();
		hummerModel.engineBoom();
		hummerModel.alarm();
		hummerModel.run();
	}

}

HummerModel:

public abstract class HummerModel {
	public abstract void start();

	public abstract void stop();

	public abstract void alarm();// 喇叭鸣叫

	public abstract void engineBoom();// 引擎发出轰鸣声

	public abstract void run();
}

HummerH1Model1

package com.sanyinchen.templete;

public class HummerH1Model1 extends HummerModel {

	@Override
	public void start() {
		// TODO Auto-generated method stub
		System.out.println("HummerH1Model1启动了");
	}

	@Override
	public void stop() {
		// TODO Auto-generated method stub
		System.out.println("HummerH1Model1停止了");
	}

	@Override
	public void alarm() {
		// TODO Auto-generated method stub
		System.out.println("HummerH1Model1喇叭叫了");
	}

	@Override
	public void engineBoom() {
		// TODO Auto-generated method stub
		System.out.println("HummerH1Model1引擎启动了");
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("HummerH1Model1跑起来了");

	}

}

HummerH1Model2

public class HummerH1Model2 extends HummerModel {

	@Override
	public void start() {
		// TODO Auto-generated method stub
		System.out.println("HummerH1Model2启动了");
	}

	@Override
	public void stop() {
		// TODO Auto-generated method stub
		System.out.println("HummerH1Model2停止了");
	}

	@Override
	public void alarm() {
		// TODO Auto-generated method stub
		System.out.println("HummerH1Model2喇叭叫了");
	}

	@Override
	public void engineBoom() {
		// TODO Auto-generated method stub
		System.out.println("HummerH1Model2引擎启动了");
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("HummerH1Model2跑起来了");

	}

}

程序运行的结构:

HummerH1Model1启动了
HummerH1Model1引擎启动了
HummerH1Model1喇叭叫了
HummerH1Model1跑起来了
--------------------
HummerH1Model2启动了
HummerH1Model2引擎启动了
HummerH1Model2喇叭叫了
HummerH1Model2跑起来了

当然,我们可以将每一步封装在run方法里:

HummerH1Model3:

package com.sanyinchen.templete;

public class HummerH1Model3 extends HummerModel {

	@Override
	public void start() {
		// TODO Auto-generated method stub
		System.out.println("HummerH1Model3启动了");
	}

	@Override
	public void stop() {
		// TODO Auto-generated method stub
		System.out.println("HummerH1Model3停止了");
	}

	@Override
	public void alarm() {
		// TODO Auto-generated method stub
		System.out.println("HummerH1Model3喇叭叫了");
	}

	@Override
	public void engineBoom() {
		// TODO Auto-generated method stub
		System.out.println("HummerH1Model3引擎启动了");
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		this.start();
		this.engineBoom();
		this.alarm();
		System.out.println("HummerH1Model3跑起来了");

	}

}

这就是一个基本的模板设计模式,但是我们明显的可以看到会有重复代码,如果按照model3那个方式来,那么model4呢?run()里面的方法是一样的。

所以我们可以将HummerModel里的方法变为实现方法,所以在其他model继承的它的时候自然不需要再次实现它。

模板方法的优点:

(1)封装不变部分,扩展可变部分

(2)提取公共部分代码,便于维护

(3)行为由父类控制,子类实现

模板方法模式使用场景:

(1)多个子类有公有的方法,并且逻辑基本相同

(2)重要,复杂的代码,可以把核心算法设计为模板方法,周边相关细节功能则由各个子类实现

(3)重构时,模板方法模式是一个经常使用的模式,把相同的代码抽到父类中,然后通过钩子函数约束其行为。

模板方法的扩展:

下面需要修改一下需求,model1和model2的喇叭响不响是有控制的,因此添加一个钩子函数。

修改之后的类图:

Client

package com.sanyinchen.templete2;

/**
 * 模板方法模式 钩子函数使用
 *
 * @author sanyinchen
 *
 */
public class Client {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		HummerModel hummerModel = new HummerH1Model1();
		hummerModel.run();
		System.out.println("--------------------");
		hummerModel = new HummerH1Model2();
		hummerModel.run();
		System.out.println("--------------------");
		HummerH1Model3 hummerMode3 = new HummerH1Model3();
		hummerMode3.steAram(false);
		hummerMode3.run();
	}

}

HummerModel:

package com.sanyinchen.templete2;

public abstract class HummerModel {
	public abstract void start();

	public abstract void stop();

	public abstract void alarm();// 喇叭鸣叫

	public abstract void engineBoom();// 引擎发出轰鸣声

	public abstract boolean isAlarm();

	public void run() {
		// TODO Auto-generated method stub
		this.start();
		this.engineBoom();
		this.alarm();
	}
}

HummerH1Model3

package com.sanyinchen.templete2;

public class HummerH1Model3 extends HummerModel {

	private boolean isArm = true;

	@Override
	public void start() {
		// TODO Auto-generated method stub
		System.out.println("HummerH1Model3启动了");
	}

	@Override
	public void stop() {
		// TODO Auto-generated method stub
		System.out.println("HummerH1Model3停止了");
	}

	@Override
	public void alarm() {
		// TODO Auto-generated method stub
		if(this.isAlarm())
		System.out.println("HummerH1Model3喇叭叫了");
	}

	@Override
	public void engineBoom() {
		// TODO Auto-generated method stub
		System.out.println("HummerH1Model3引擎启动了");
	}

	@Override
	public boolean isAlarm() {
		// TODO Auto-generated method stub
		return this.isArm;
	}

	public void steAram(boolean flag) {
		this.isArm = flag;
	} }

运行结果:

HummerH1Model1启动了
HummerH1Model1引擎启动了
HummerH1Model1喇叭叫了
--------------------
HummerH1Model2启动了
HummerH1Model2引擎启动了
HummerH1Model2喇叭叫了
--------------------
HummerH1Model3启动了
HummerH1Model3引擎启动了

由此可以看出model3要不要响喇叭是由场景类决定的。

时间: 2025-01-18 08:53:54

设计模式之禅-模板方法模式的相关文章

设计模式之禅——模板方法模式&钩子方法

** 模 **板方法模式的定义: 定义一个操作的算法的框架,而将一些步骤延迟到子类中.使得子类可以不改变一个算法的框架即可重定义该算法的某些特定步骤. 例子:做一个简单的悍马车的模型 见UML图 一个抽象悍马模型类 HummerModel,然后有两个悍马具体型号的实现 类.见代码 public abstract class HummerModel { //发动了 protected abstract void start(); //停下了 protected abstract void stop

设计模式C++实现——模板方法模式

模式定义: 模板方法模式在一个方法中定义了一个算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤. 模板就是一个方法.更具体的说,这个方法将算法定义成一组步骤,其中的任何步骤都可以是抽象的,由子类实现.这可以确保算法的结果保持不变,同时由子类提供部分实现. 模式结构: 举例: 泡咖啡和泡茶步骤与基本相同,定义咖啡和茶的类如下: class Coffee { public: void prepareRecipe() { boilWater(

设计模式--15、模板方法模式

设计模式学习笔记-模板方法模式 1. 概述 定义一个操作中的算法的骨架,而将步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义算法的某些特定步骤. 2. 模式中的角色 2.1 抽象类(AbstractClass):实现了模板方法,定义了算法的骨架. 2.2 具体类(ConcreteClass):实现抽象类中的抽象方法,已完成完整的算法. 3. 模式解读 3.1 模板方法类图 3.2 模板方法模式代码实现 /// <summary> /// 抽象类 /// </summa

设计模式入门之模板方法模式TemplateMethod

模板方法模式定义: 定义一个算法的骨架,而将步骤延迟到子类中.这种模式可以使得在不改变算法骨架(模板)的情况下修改每个步骤的具体实现 从功能上来看,这个模式跟生成器模式有些相像,只不过生成器模式定义了创建对象的过程,而模板方法模式定义了算法过程 感觉这个模式要简单很多. 钩子:可以被子类覆盖以实现扩展的方法通常叫做钩子 实例:用户登录过程,分为后台人员登录和用户登录,这是一个非常成型的技术过程,是非常典型的模板方法模式的应用,其中普通用户密码不需要加密,而工作人员的密码需要进行加密比对.上代码

设计模式学习之模板方法模式(TemplateMethod,行为型模式)(9)

一.什么是模板方法模式 Template Method模式也叫模板方法模式,是行为模式之一,它把具有特定步骤算法中的某些必要的处理委让给抽象方法,通过子类继承对抽象方法的不同实现改变整个算法的行为. 二.模板方法模式的应用场景 Template Method模式一般应用在具有以下条件的应用中: - 具有统一的操作步骤或操作过程 - 具有不同的操作细节 - 存在多个具有同样操作步骤的应用场景,但某些具体的操作细节却各不相同 private static void Main(string[] arg

C#设计模式之十三模板方法模式(Template Method Pattern)【行为型】

原文:C#设计模式之十三模板方法模式(Template Method Pattern)[行为型] 一.引言 "结构型"的设计模式已经写完了,从今天我们开始讲"行为型"设计模式.现在我们开始讲[行为型]设计模式的第一个模式,该模式是[模板方法],英文名称是:Template Method Pattern.还是老套路,先从名字上来看看."模板方法"我第一次看到这个名称,我的理解是,有一个方法的名字叫"模板方法",后来深入学习之后,

c#设计模式系列:模板方法模式(Template Method Pattern)

引言 提到模板,大家肯定不免想到生活中的"简历模板"."论文模板"."Word中模版文件"等,在现实生活中,模板的概念就是--有一个规定的格式,然后每个人都可以根据自己的需求或情况去更新它,例如简历模板,下载下来的简历模板的格式都是相同的,然而我们下载下来简历模板之后我们可以根据自己的情况填充不同的内容要完成属于自己的简历.在设计模式中,模板方法模式中模板和生活中模板概念非常类似,下面让我们就详细介绍模板方法的定义,大家可以根据生活中模板的概念来

Java设计模式(四) 之 模板方法模式

源码均以JDK1.8作为参考 1.定义: 定义一个操作中的算法的框架,而将一些步骤延迟到子类中.使得子类可以不改变一个算法的机构即可重定义该算法的某些特定步骤. 2.解析: 通用类图: 类图解析: 模板方法模式非常简单,仅仅使用了Java的继承机制,但它是一个应用非常广泛的模式. 2.1.抽象模板(AbstractClass) 主要定义了模板中一些基本操作(方法),它的方法分为两类: 基本方法: 基本方法也叫基本操作,是由子类实现的方法,并且被模板方法被调用. 模板方法: 可以由一个或几个,一般

设计模式—— 十 :模板方法模式

@ 目录 什么是模板方法模式? 模板方法模式的应用 模板方法模式的优点 模板方法模式的缺点 模板方法模式的使用场景 什么是模板方法模式? 模板方法模式(Template Method Pattern)定义如下: Define the skeleton of an algorithm in an operation,deferring some steps to subclasses.Template Method lets subclasses redefine certain steps of