设计模式学习笔记14 - Java版之模板模式

1. 豆浆制作问题

  1. 制作豆浆的流程 选材—>添加配料—>浸泡—>放到豆浆机打碎
  2. 通过添加不同的配料,可以制作出不同口味的豆浆
  3. 选材、浸泡和放到豆浆机打碎这几个步骤对于制作每种口味的豆浆都是一样的

2. 模板模式

2.1 基本介绍

  1. 模板方法模式(Template Method Pattern),又叫模板模式(Template Pattern),在一个抽象类公开定义了执行它的方法的模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行
  2. 简单说,模板方法模式 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构,就可以重定义该算法的某些特定步骤
  3. 行为型模式

2.2 原理类图

在这里插入图片描述

  1. AbstractClass 抽象类, 类中实现了模板方法(template),定义了算法的骨架,具体子类需要去实现 其它的抽象方法operationr2,3,4
  2. ConcreteClass 实现抽象方法operationr2,3,4, 以完成算法中特点子类的步骤

2.3 解决豆浆制作问题

在这里插入图片描述

package com.liyang;

// 1. 抽象类
public abstract class SoyaMilk {
	// 模板方法做成final防止子类重写
	final void make() {
		select();
		add();
		soak();
		beat();
	}
	
	// 选材
	void select() {
		System.out.println("开始选材...");
	}
	
	// 添加作料, 这个抽象方法子类去实现
	abstract void add();
	
	// 浸泡
	void soak() {
		System.out.println("浸泡...");
	}
	
	// 打碎
	void beat() {
		System.out.println("打碎...");
	}
}
package com.liyang;

// 2. 花生豆浆
public class PeanutSoyaMilk extends SoyaMilk{

	@Override
	void add() {
		System.out.println("添加花生...");
	}
	
}
package com.liyang;

// 3. 测试
public class Client {

	public static void main(String[] args) {
		PeanutSoyaMilk peanutSoyaMilk = new PeanutSoyaMilk();
		peanutSoyaMilk.make();
	}

}

2.4 钩子方法

  1. 在模板方法模式的父类中,我们可以定义一个方法,它默认不做任何事,子类可以视情况要不要覆盖它,该方法称为“钩子”
  2. 比如,我们还希望制作纯豆浆,不添加任何的配料,请使用钩子方法对前面的模板方法进行改造
package com.liyang;

// 1. 抽象类
public abstract class SoyaMilk {
	// 模板方法做成final防止子类重写
	final void make() {
		select();
		if (isAdd()) {
			add();
		}
		soak();
		beat();
	}
	
	// 选材
	void select() {
		System.out.println("开始选材...");
	}
	
	// 添加作料, 这个抽象方法子类去实现
	abstract void add();
	
	// 浸泡
	void soak() {
		System.out.println("浸泡...");
	}
	
	// 打碎
	void beat() {
		System.out.println("打碎...");
	}
	
	// 钩子方法
	boolean isAdd() {
		return true;
	}
}
package com.liyang;

// 2. 花生豆浆
public class PeanutSoyaMilk extends SoyaMilk{

	@Override
	void add() {
		System.out.println("添加花生...");
	}
	
}
package com.liyang;

// 3. 制作纯豆浆
public class Milk extends SoyaMilk{

	@Override
	void add() {
		
	}
	
	@Override
	boolean isAdd() {
		return false;
	}

}
package com.liyang;

// 4. 测试
public class Client {

	public static void main(String[] args) {
		PeanutSoyaMilk peanutSoyaMilk = new PeanutSoyaMilk();
		peanutSoyaMilk.make();
		
		Milk milk = new Milk();
		milk.make();
	}

}

2.5 细节

  1. 基本思想是:算法只存在于一个地方,也就是在父类中,容易修改。需要修改算法时,只要修改父类的模板方法或者已经实现的某些步骤,子类就会继承这些修改
  2. 实现了最大化代码复用。父类的模板方法和已实现的某些步骤会被子类继承而直接使用
  3. 既统一了算法,也提供了很大的灵活性。父类的模板方法确保了算法的结构保持不变,同时由子类提供部分步骤的实现
  4. 该模式的不足之处:每一个不同的实现都需要一个子类实现,导致类的个数增加,使得系统更加庞大
  5. 一般模板方法都加上final关键字, 防止子类重写模板方法
  6. 模板方法模式使用场景:当要完成在某个过程,该过程要执行一系列步骤 ,这一系列的步骤基本相同,但其个别步骤在实现时 可能不同,通常考虑用模板方法模式来处理
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值