《Head First设计模式》已经读了不止一遍,但是始终没有进行系统的进行总结。所以近期开始总结设计模式相关的知识,从模板方法模式开始,因为是一个我认为是最简单的设计模式。(推荐视频资源23个设计模式)
提出问题
实现制作咖啡功能。且制作咖啡需要四个步骤 :
代码实现
/** * 一杯加糖咖啡 * * @author Jann Lee * @date 2019-07-14 18:37 */public class Coffee { /** * 制作一杯加糖咖啡 */ public void prepareRecipe() { boilWater(); steepTeaBag(); portInCup(); addLemon(); } /** * step1: 烧水 */ private void boilWater() { System.out.println("烧水..."); } /** * step2:冲泡咖啡 */ private void steepTeaBag() { System.out.println("冲泡咖啡..."); } /** * step3: 倒入杯中 */ private void portInCup() { System.out.println("倒入杯中..."); } /** * step4: 加糖 */ private void addLemon() { System.out.println("加糖..."); }
/**
* 一杯加糖咖啡
*
* @author Jann Lee
* @date 2019-07-14 18:37
*/
public class Coffee {
* 制作一杯加糖咖啡
public void prepareRecipe() {
boilWater();
steepTeaBag();
portInCup();
addLemon();
}
* step1: 烧水
private void boilWater() {
System.out.println("烧水...");
* step2:冲泡咖啡
private void steepTeaBag() {
System.out.println("冲泡咖啡...");
* step3: 倒入杯中
private void portInCup() {
System.out.println("倒入杯中...");
* step4: 加糖
private void addLemon() {
System.out.println("加糖...");
再次提出问题此时此刻我需要一杯柠檬茶呢?【烧水,冲泡茶包,倒入杯中,加柠檬】
这个问题当然很简单,我们只需要如法炮制即可。
public class Tea { /** * 制作一杯柠檬茶 */ public void prepareRecipe(){ boilWater(); brewCoffeeGrinds(); portInCup(); addSugarAndMilk(); } /** * step1: 烧水 */ private void boilWater() { System.out.println("烧水..."); } /** * step2:冲泡咖啡 */ private void brewCoffeeGrinds() { System.out.println("冲泡茶包..."); } /** * step3: 倒入杯中 */ private void portInCup() { System.out.println("倒入杯中..."); } /** * step4: 加柠檬 */ private void addSugarAndMilk() { System.out.println("加入柠檬片..."); }}
public class Tea {
* 制作一杯柠檬茶
public void prepareRecipe(){
brewCoffeeGrinds();
addSugarAndMilk();
private void brewCoffeeGrinds() {
System.out.println("冲泡茶包...");
* step4: 加柠檬
private void addSugarAndMilk() {
System.out.println("加入柠檬片...");
思考
? 如果此时我们又需要一杯不加柠檬的茶,加奶的咖啡...,当然我们可以按照上面方式重新依次实现即可。但是如果你是一个有经验的程序员,或者你学习过设计模式。你可能会发现以上功能实现的步骤/流程固定,当需求发生变化时,只有小部分步骤有所改变。
根据面向对象程序的特点,既抽象,封装,继承,多态。我们可以对代码进行抽象,将公共代码提取到基类。我们将咖啡和茶抽象成咖啡因饮料,将其中相同的两步,烧水和倒入杯中再父类中实现,将冲泡和添加调料延迟到子类。
public abstract class CafeineBeverage { /** * 制作一杯咖啡因饮料 */ public void prepareRecipe() { boilWater(); brew(); portInCup(); addCondiments(); } /** * step1: 烧水 */ private void boilWater() { System.out.println("烧水..."); } /** * step2:冲泡 */ protected abstract void brew(); /** * step3: 入杯中 */ private void portInCup() { System.out.println("倒入杯中..."); } /** * step4: 加调料 */ protected abstract void addCondiments();}
public abstract class CafeineBeverage {
* 制作一杯咖啡因饮料
brew();
addCondiments();
* step2:冲泡
protected abstract void brew();
* step3: 入杯中
* step4: 加调料
protected abstract void addCondiments();
// 一杯加糖咖啡public class CoffeeBeverage extends CafeineBeverage{ @Override protected void brew() { System.out.println("冲泡咖啡..."); } @Override protected void addCondiments() { System.out.println("加糖..."); }}
// 一杯加糖咖啡
public class CoffeeBeverage extends CafeineBeverage{
@Override
protected void brew() {
protected void addCondiments() {
// 一杯柠檬茶public class TeaBeverage extends CafeineBeverage { @Override protected void brew() { System.out.println("冲泡茶包..."); } @Override protected void addCondiments() { System.out.println("加柠檬..."); }}
// 一杯柠檬茶
public class TeaBeverage extends CafeineBeverage {
System.out.println("加柠檬...");
如果按以上方式对代码进行了优化,其实就实现了模板方法模式。一下是模板方法模式相关概念。
动机
定义
定义一个操作中算法的骨架(稳定),而将一些步骤延迟(变化)到子类。Template Method使得子类可以不改变(复用)一个算法的结构,即可重新定义(override)该算法的特定步骤。
要点总结
类图:
个人博客网站(正在建设中)
原文链接:http://www.cnblogs.com/liqiangchn/p/11186438.html
本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728