目录
DayInXueMing、DayInHaoLin、DayInWanXiong是具体的实现类
1.前言
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因。
六大原则
1.开闭原则 就是说对扩展开放,对修改关闭 简单点说就是对程序扩展的时候不能去修改原来的代码,实现热插拔的效果
2.里氏代换原则 说的是任何基类可以出现的地方,子类一定可以出现。
3.依赖倒转原则 针对接口编程,依赖于抽象而不依赖具体。
4.接口隔离原则 意思是是用多个隔离的接口,比使用单个接口要好。 降低类之间的耦合度 降低依赖,降低耦合,为了方便升级、维护。
5.迪米特法则 就是最少知道原则 就是一个实体应当尽量更少的和其他实体相互交互,让模块和模块之间跟独立
6.合成复用原则 尽量使用合成聚合的方式,而不是使用继承。
2.背景
总体来说设计模式分为三大类,创建型模式、结构型模式、行为型模式
模板方法在这里属于行为性模式,在一个抽象类公开定义了执行它的方法的模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。
简单说,模板方法模式定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构,就可以重定义该算法的某些特定步骤。
下面以一个人的一天为例 比如每个一天从早晨到第二天的凌晨 其中早晨、中午、凌晨每个人都是一样的,其他时间段做的是不同的事情。所以比较适合用模板方法来实现。
上代码 ↓↓↓↓↓↓↓↓
3.实现
Day是一个抽象类
/**
* 描 述:模板方法
* 创 建 者:wby
* 创建时间:2024/8/9 10:03
*/
// 抽象类: 🐂🐎的一天
public abstract class Day {
// 模板方法为final不允许子类override
public final void templateMethod() {
System.out.println("🐂🐎的一天开始了=====================");
//早晨
morning();
//上午
forenoon();
//中午
noon();
//下午
afternoon();
//晚上
night();
//凌晨
beforeDawn();
System.out.println("🐂🐎的一天结束了=====================");
}
//private 对外不可见 早上
private void morning() {
System.out.println("早上起床洗漱");
}
//private 对外不可见 中午
private void noon() {
System.out.println("中午去饭店吃饭");
}
//private 对外不可见 凌晨
private void beforeDawn() {
System.out.println("凌晨在睡觉");
}
public abstract void forenoon();
public abstract void afternoon();
public abstract void night();
}
DayInXueMing、DayInHaoLin、DayInWanXiong是具体的实现类
/**
* 描 述:小李的一天
* 创 建 者:wby
* 创建时间:2024/8/9 10:32
*/
public class DayInXueMing extends Day {
@Override
public void forenoon() {
System.out.println("小李上午骑车去上班");
}
@Override
public void afternoon() {
System.out.println("小李下午在思考maven依赖为什么导不进去");
}
@Override
public void night() {
System.out.println("小李晚上去健身房锻炼");
}
}
/**
* 描 述:小解的一天
* 创 建 者:wby
* 创建时间:2024/8/9 10:32
*/
public class DayInHaoLin extends Day {
@Override
public void forenoon() {
System.out.println("小解上午居家办公");
}
@Override
public void afternoon() {
System.out.println("小解下午在想java怎么操作word文档");
}
@Override
public void night() {
System.out.println("小解晚上和朋友把酒言欢");
}
}
/**
* 描 述:小熊的一天
* 创 建 者:wby
* 创建时间:2024/8/9 10:32
*/
public class DayInWanXiong extends Day {
@Override
public void forenoon() {
System.out.println("小熊上午正在补觉");
}
@Override
public void afternoon() {
System.out.println("小熊下午躺在床上刷着抖音");
}
@Override
public void night() {
System.out.println("小熊晚上依旧躺在床上刷着抖音");
}
}
客户端(调用者)
/**
* 描 述:test
* 创 建 者:wby
* 创建时间:2024/8/9 10:57
*/
public class DayProcess {
public static void main(String[] args) {
Day xueMing = new DayInXueMing();
xueMing.templateMethod();
Day haoLin = new DayInHaoLin();
haoLin.templateMethod();
Day wanXiong = new DayInWanXiong();
wanXiong.templateMethod();
}
}
输出结果
实现方式:
抽象类有一个模板方法和其他行为方法,模板方法按流程调用各行为方法(抽象或非抽象);具体子类重写抽象的行为方法。
对原理类图的说明——即模板方法模式的角色和职责
DayClass
抽象类中实现了模板方法,定义了骨架,具体子类需要去实现其抽象方法或重写其中方法
- 实现抽象方法,已完成特定子类的步骤
4.应用
AbstractApplicationContext.java中有一个refresh()方法就是模板方法,它用于根据流程调用aop代理创建、bean生命周期初始化、属性注入等启动并初始化Spring应用上下文的方法。
-
当要完成在某个过程,该过程要执行一系列步骤 ,这一系列的步骤基本相同,但其个别步骤在实现时可能不同,通常考虑用模板方法模式来处理
-
统计某一段代码的执行时间也可以用模板方法模式:在前面打印出代码执行前的时间,后面再打印出代码执行后的时间,中间部分就是不同的执行代码
不足之处:
每一个不同的实现都需要一个子类实现,导致类的个数增加,使得系统更加庞大
5.扩展
钩子方法
在模板方法模式的父类中,我们可以定义一个方法,它默认不做任何事,子类可以视情况要不要覆盖它,该方法称为“钩子”