设计模式 模板方法模式

01.如果接到一个任务,要求设计不同型号的悍马车
在这里插入图片描述
02.设计一个悍马车的抽象类(模具,车模)

public abstract class HummerModel {
	/*
	 * 首先,这个模型要能够被发动起来,别管是手摇发动,还是电力发动,反正
	 * 是要能够发动起来,那这个实现要在实现类里了
	 */
	public abstract void start(); 
	 
	//能发动,那还要能停下来,那才是真本事
	public abstract void stop(); 
	
	//喇叭会出声音,是滴滴叫,还是哔哔叫
	public abstract void alarm(); 
	 
	//引擎会轰隆隆的响,不响那是假的
	public abstract void engineBoom(); 
	 
	//那模型应该会跑吧,别管是人推的,还是电力驱动,总之要会跑
	public abstract void run(); 
} 

03.具体不同版本的悍马,这个是抽象类的具体子类

H1 型号悍马的定义如下:

public class HummerH1Model extends HummerModel { 
	
   @Override 
	public void alarm() { 
		 System.out.println("悍马H1鸣笛..."); 
	 } 
	 
	@Override
	public void engineBoom() { 
		 System.out.println("悍马H1引擎声音是这样在..."); 
	 } 
	 
	@Override
	public void start() { 
		 System.out.println("悍马H1发动..."); 
	 }
	  
	@Override
	public void stop() { 
		 System.out.println("悍马H1停车..."); 
	 } 
	 
	/*
	* 这个方法是很有意思的,它要跑,那肯定要启动,停止了等,也就是要调其他方法
	 */
	@Override
	public void run() { 
	 
		 //先发动汽车
		 this.start(); 
		 
		 //引擎开始轰鸣
		 this.engineBoom(); 
		 
		 //然后就开始跑了,跑的过程中遇到一条狗挡路,就按喇叭
		 this.alarm(); 
		 
		 //到达目的地就停车
		 this.stop(); 
	 } 
} 

然后看悍马 H2 型号的实现:

public class HummerH2Model extends HummerModel { 

	@Override
	public void alarm() { 
		 System.out.println("悍马H2鸣笛..."); 
	 } 
	
	@Override
	public void engineBoom() { 
		 System.out.println("悍马H2引擎声音是这样在..."); 
	 } 
	
	@Override
	public void start() { 
		System.out.println("悍马H2发动..."); 
	 } 
	
	@Override
	public void stop() { 
	 	System.out.println("悍马H1停车..."); 
	 } 
	 
	/*
	 * H2要跑,那肯定要启动,停止了等,也就是要调其他方法
	 */
	@Override
	public void run() { 
	 
		 //先发动汽车
		 this.start(); 
		 
		 //引擎开始轰鸣
		 this.engineBoom(); 
		 
		 //然后就开始跑了,跑的过程中遇到一条狗挡路,就按喇叭
		 this.alarm(); 
		 
		 //到达目的地就停车
		 this.stop(); 
	 } 
}

然后程序写到这里,你就看到问题了,run 方法的实现应该在抽象类上(子类改写的都一样),不应该在实现类上,好,我们修改一下类图和实现:
在这里插入图片描述

就把 run 方法放到了抽象类中,那代码也相应的改变一下,先看 HummerModel.java:

04.修改后的抽象类

public abstract class HummerModel { 
	/*
	 * 首先,这个模型要能够被发动起来,别管是手摇发动,还是电力发动,反正
	 * 是要能够发动起来,那这个实现要在实现类里了
	 */
	public abstract void start(); 
	 
	//能发动,那还要能停下来,那才是真本事
	public abstract void stop(); 
	 
	//喇叭会出声音,是滴滴叫,还是哔哔叫
	public abstract void alarm(); 
	 
	//引擎会轰隆隆的响,不响那是假的

	public abstract void engineBoom(); 
 
	//那模型应该会跑吧,别管是人退的,还是电力驱动,总之要会跑
	public void run() { 
	 
	 //先发动汽车
	 this.start(); 
	 
	 //引擎开始轰鸣
	 this.engineBoom(); 
	 
	 //然后就开始跑了,跑的过程中遇到一条狗挡路,就按喇叭
	 this.alarm(); 
	 
	 //到达目的地就停车
	 this.stop(); 
	 } 
}

05.修改后的抽象类的子类:

public class HummerH1Model extends HummerModel { 

	 @Override 
	public void alarm() { 
		 System.out.println("悍马H1鸣笛..."); 
	 } 
	 
	@Override
	public void engineBoom() { 
		 System.out.println("悍马H1引擎声音是这样在..."); 
	 } 
	 
	@Override
	public void start() { 
		 System.out.println("悍马H1发动..."); 
	  }
	   
	@Override
	public void stop() { 
		 System.out.println("悍马H1停车..."); 
	 } 
 
} 
public class HummerH2Model extends HummerModel { 

	@Override
	public void alarm() { 
		 System.out.println("悍马H2鸣笛..."); 
	 } 
	 
	@Override
	public void engineBoom() { 
	 	System.out.println("悍马H2引擎声音是这样在..."); 
	 } 
	 
	@Override
	public void start() { 
		 System.out.println("悍马H2发动..."); 
	 } 
	 
	@Override
	public void stop() { 
		 System.out.println("悍马H2停车..."); 
	 } 
 
}

06.运行程序
在这里插入图片描述

public class Client { 
	public static void main(String[] args) { 
	 
	 //客户开着H1型号,出去遛弯了
	 HummerModel h1 = new HummerH1Model(); 
	 h1.run(); //汽车跑起来了;
	 
	 //客户开H2型号,出去玩耍了
	 HummerModel h2 = new HummerH2Model(); 
	 h2.run(); 
	 } 
}

在这里插入图片描述

07.客户只要在 run 的过程中,听到或看都成了呀,暴露那么多的方法干啥?把抽象方法保护起来
在这里插入图片描述
把抽象类上的四个方法设置为 protected 访问权限,好了,既然客户不关心这几个方法,而且这四个方法都是由子类来实现的,那就设置成 protected 模式。咦~,那还有个缺陷,run 方法既然子类都不修改,那是不是可以设置成 final 类型呢?是滴是滴,类图如下:
在这里插入图片描述

public abstract class HummerModel { 
	/*
	 * 首先,这个模型要能够被发动起来,别管是手摇发动,还是电力发动,反正
	 * 是要能够发动起来,那这个实现要在实现类里了
	 */
	protected abstract void start(); 
	 
	//能发动,那还要能停下来,那才是真本事
	protected abstract void stop(); 
	 
	//喇叭会出声音,是滴滴叫,还是哔哔叫
	protected abstract void alarm(); 
	 
	//引擎会轰隆隆的响,不响那是假的
	protected abstract void engineBoom(); 
	 
	//那模型应该会跑吧,别管是人退的,还是电力驱动,总之要会跑
	final public void run() { 
 
		 //先发动汽车
		 this.start(); 
		 
		 //引擎开始轰鸣
		 this.engineBoom(); 
		 
		 //然后就开始跑了,跑的过程中遇到一条狗挡路,就按喇叭
		 this.alarm(); 
		 
		 //到达目的地就停车
		 this.stop(); 
	 } 
} 

大家请看这个 run 方法,他定义了调用其他方法的顺序,并且子类是不能修改的,这个叫做模板方法;start、stop、alarm、engineBoom 这四个方法是子类必须实现的,而且这四个方法的修改对应了不同的类,这个叫做基本方法,基本方法又分为三种:在抽象类中实现了的基本方法叫做具体方法;在抽象类中没有实现,在子类中实现了叫做抽象方法,我们这四个基本方法都是抽象方法,由子类来实现的;还有一种叫做钩子方法,

相关推荐

  1. 设计模式-模板方法模式

    2024-03-20 13:34:01       66 阅读
  2. 设计模式模板方法模式

    2024-03-20 13:34:01       54 阅读
  3. 设计模式——模板方法模式

    2024-03-20 13:34:01       61 阅读
  4. 设计模式: 模板方法模式

    2024-03-20 13:34:01       44 阅读
  5. 设计模式---模板方法模式

    2024-03-20 13:34:01       31 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-20 13:34:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-20 13:34:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-20 13:34:01       82 阅读
  4. Python语言-面向对象

    2024-03-20 13:34:01       91 阅读

热门阅读

  1. InitializingBean学习

    2024-03-20 13:34:01       45 阅读
  2. 机器学习 - PyTorch使用流程

    2024-03-20 13:34:01       43 阅读
  3. TCP总结

    TCP总结

    2024-03-20 13:34:01      40 阅读
  4. 学习大数据,所需要的SQL基础(3)

    2024-03-20 13:34:01       44 阅读
  5. 深入理解与使用go之错误处理--实现

    2024-03-20 13:34:01       44 阅读
  6. 一文解读ISO26262安全标准:技术安全概念TSC

    2024-03-20 13:34:01       55 阅读
  7. MongoDB聚合运算符:$getField

    2024-03-20 13:34:01       45 阅读
  8. Web框架开发-Django-模板继承和静态文件配置

    2024-03-20 13:34:01       41 阅读
  9. Windows 11 安装 Scoop

    2024-03-20 13:34:01       39 阅读
  10. Web框架开发-Django的模板层

    2024-03-20 13:34:01       36 阅读
  11. Python Web开发记录 Day15:Django part9 数据统计

    2024-03-20 13:34:01       39 阅读
  12. 如何动态修改spring中定时任务的调度策略(1)

    2024-03-20 13:34:01       37 阅读