模板方法

模板类定义了实现功能的步骤, 但是具体实现需要子类提供. 这使得一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

模板方法的核心在于定义一个“骨架”。

public abstract class Worker
{
	protected String name;
 
	public Worker(String name)
	{
		this.name = name;
	}
 
	/**
	 * 记录一天的工作
	 */
	public final void workOneDay()
	{
 
		System.out.println("-----------------work start ---------------");
		enterCompany();
		computerOn();
		work();
		computerOff();
		exitCompany();
		System.out.println("-----------------work end ---------------");
 
	}
 
	/**
	 * 打代码
	 */
	public abstract void work();
 
	/**
	 * 关闭电脑
	 */
	private void computerOff()
	{
		System.out.println(name + "关闭电脑");
	}
 
	/**
	 * 打开电脑
	 */
	private void computerOn()
	{
		System.out.println(name + "打开电脑");
	}
 
	/**
	 * 进入公司
	 */
	public void enterCompany()
	{
		System.out.println(name + "进入公司");
	}
 
	/**
	 * 离开公司
	 */
	public void exitCompany()
	{
		System.out.println(name + "离开公司");
	}
 
}

其中大部分方法都实现了(演示方便, 有返回值就行) 唯独打代码没实现, 那么这个方法延迟到子类实现, 我们看下孩子们是如何实现的 劳大:

public class ITWorker extends Worker
{
 
	public ITWorker(String name)
	{
		super(name);
	}
 
	@Override
	public void work()
	{
		System.out.println(name + "孩子们快跑, 我在finally返回了");
	}
 
}

皮衣黄

public class HRWorker extends Worker
{
 
	public HRWorker(String name)
	{
		super(name);
	}
 
	@Override
	public void work()
	{
		System.out.println(name + "孩子们快跑, deepseek跳过了CUDA");
	}
 
}

马圣

public class QAWorker extends Worker
{
 
	public QAWorker(String name)
	{
		super(name);
	}
 
	@Override
	public void work()
	{
		System.out.println(name + "孩子们快跑, DOGE要开人啦");
	}
 
}

这样所有子类只需完成小部分逻辑即可实现功能

![[content/en/java/Basic/Concurrent/Pasted image 20250203230102.png]]

钩子

[!NOTE] 钩子的由来:

  • “钩子” 这个名字形象地表达了方法在模板方法模式中的角色:它就像一个钩子,可以被子类“挂”上去(重写),也可以“留空”。
  • 子类重写钩子方法,就相当于“挂”上去了,它能改变或增加一些行为;如果不重写钩子方法,就相当于“没挂”——这时模板方法会使用父类提供的默认实现。
  • 可以当成开关理解

父类可以留几个钩子 比如是否打印时间

public boolean isNeedPrintDate()
	{
		return false;
	}
	/**
	 * 离开公司
	 */
	public void exitCompany()
	{
		if (isNeedPrintDate())
		{
			System.out.print(new Date().toLocaleString()+"-->");
		}
		System.out.println(name + "离开公司");
	}

子类重写钩子, 就可以选择算法分支了, 也就是是否打印时间

	@Override
	public boolean isNeedPrintDate()
	{
		return true;
	}
	

总结: 其实模板方法就是把一类操作提取出统一的逻辑 将不同的参数, 细节等延迟到子类实现

[!引用] https://blog.csdn.net/lmj623565791/article/details/26276093