一、前言
1.1 背景
当你只希望客户端扩展某个特定算法步骤, 而不是整个算法或其结构时;
当多个类的算法除一些细微不同之外几乎完全一样时;
1.2 简介
模板方法模式是一种行为型设计模式,它定义了一个算法的骨架,将部分逻辑以具体方法的形式实现,并声明一些抽象方法来迫使子类实现剩余的逻辑。
核心思想是封装不变部分,扩展可变部分,提取公共部分代码,便于维护,行为由父类控制,子类实现。在模板方法模式中,抽象类定义了算法的骨架,包括一系列抽象方法和可能包含的钩子函数,允许具体实现类按需重写某些步骤。具体实现类继承抽象类并实现抽象方法,以及可能被重写的钩子函数,从而对算法的某些步骤进行具体的实现。
优点:
- 减少重复代码
- 可扩展性
- 便于维护
缺点:
- 部分客户端可能会受到算法框架的限制
- 通过子类抑制默认步骤实现可能会导致违反里氏替换原则
- 模板方法中的步骤越多, 其维护工作就可能会越困难
组成部分:
- 抽象类(Abstract Class):负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。
1.1 模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法
1.2 基本方法:是实现算法各个步骤的方法,是模板方法的组成部分
基本方法又可以分为三种:
抽象方法(Abstract Method) :一个抽象方法由抽象类声明、由其具体子类实现。
具体方法(Concrete Method) :一个具体方法由一个抽象类或具体类声明并实现,其子类可以进行覆盖也可以直接继承。
钩子方法(Hook Method) :在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种。 - 具体子类(Concrete Class):实现抽象类中所定义的抽象方法和钩子方法,它们是一个顶级逻辑的组成步骤。
二、案例代码
package com.qiangesoft.design.behavioral.templatemethod;
/**
* 模板方法模式
*/
public class TemplateMethod {
public static void main(String[] args) {
// 京东
Shopping shopping = new JdShopping();
shopping.shop();
System.out.println("--------------------------");
// 淘宝
Shopping shopping1 = new TbShopping();
shopping1.shop();
}
}
/**
* 1.模板类
* ps:购物功能
*/
abstract class Shopping {
/**
* 1.模板方法
* ps:购物流程
*/
public final void shop() {
// 挑选
select();
// 下单
order();
// 支付
boolean payFlag = pay();
// 邮寄
if (!payFlag) {
return;
}
delivery();
// 签收
sign();
}
/**
* 2.基本方法
*/
/**
* 2.1 具体方法
*/
private void select() {
System.out.println("挑选");
}
private void order() {
System.out.println("下单");
}
private void sign() {
System.out.println("签收");
}
/**
* 2.1 抽象方法
*/
abstract boolean pay();
abstract void delivery();
}
/**
* 2.具体子类
*/
// 京东购物
class JdShopping extends Shopping {
@Override
boolean pay() {
System.out.println("支付:微信");
return true;
}
@Override
void delivery() {
System.out.println("邮寄:京东快递");
}
}
// 淘宝购物
class TbShopping extends Shopping {
@Override
boolean pay() {
System.out.println("支付:支付宝");
return true;
}
@Override
void delivery() {
System.out.println("邮寄:平台卖家安排快递");
}
}