模板设计模式_23种设计模式之模板设计模式

模板设计模式是一种行为型设计模式,定义了算法的骨架,将部分步骤延迟到子类中,允许子类不改变算法结构就重定义特定步骤。模式包括抽象模板和具体模板角色,适用于有共同逻辑但实现不同的场景。优点是扩展性和维护性好,缺点是可能导致类数量增加。常见应用场景包括代码中存在多个子类共享的逻辑方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基本介绍

1.模板方法模式(Template Method Pattern),又叫模板模式(Template Pattern),在一个抽象类公开定义了执行它的模板。它的子类可以俺需要重写方法实现,但调用将以抽象类中定义的方式进行;

2.简单说,模板方法模式定义一个操作中的算法的骨架,而降一些步骤延迟到子类中,使得子类可以不改变一个算法的结构,就可以重定义该算法的某些特定步骤;

3.这些类型的设计模式属于行为型模式。

原理类图

b055a8e81927d1a7f44ad234430a4b55.png

角色及职责

模板模式主要是由抽象模板(Abstarct Template)角色和具体的模板(Concrete Template)角色组成。

1.抽象模板(Abstract Template): 定义了一个或多个抽象操作,以便让子类实现。这些抽象操作叫做基本操作,它们是一个顶级逻辑的组成步骤;定义并实现了一个模板方法。这个模板方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现。顶级逻辑也有可能调用一些具体方法。

2.具体模板(Concrete Template): 实现父类所定义的一个或多个抽象方法,它们是一个顶级逻辑的组成步骤;每一个抽象模板角色都可以有任意多个具体模板角色与之对应,而每一个具体模板角色都可以给出这些抽象方法(也就是顶级逻辑的组成步骤)的不同实现,从而使得顶级逻辑的实现各不相同。

代码

以下将以不同事务放入冰箱为例

冰箱类

/** * 冰箱抽象类 * * @author Api * @DATA 2020/3/24 1:08 */public abstract class Refrigerator {    //把物品放入冰箱仅需要三步,第一步打开冰箱门,第二步把物品放进去,第三步关闭冰箱门    //必须定义为final,不允许子类进行重写    final void operating() {        openDoor();        putInto();        close();    }    //第一步打开冰箱门    private void openDoor() {        System.out.println("打开冰箱门");    }    //第二步把物品放入进冰箱    abstract void putInto();    //第三步关闭冰箱门    private void close() {        System.out.println("关闭冰箱门");    }}

大象具体实现类

/** * 大象,具体的实现子类 * * @author Api * @DATA 2020/3/24 1:07 */public class Elephant extends Refrigerator {    @Override    void putInto() {        System.out.println("把大象放进去");    }}

猪具体实现类

/** * 猪,具体的实现子类 * * @author Api * @DATA 2020/3/24 1:07 */public class Pig extends Refrigerator{    @Override    void putInto() {        System.out.println("把猪放进去");    }}

测试类

/** * 测试类 * * @author Api * @DATA 2020/3/24 1:07 */public class Client {    public static void main(String[] args) {        Refrigerator pig = new Pig();        pig.operating();        System.out.println("----------------------------------");        Refrigerator elephant = new Elephant();        elephant.operating();    }}

执行结果为

打开冰箱门把猪放进去关闭冰箱门----------------------------------打开冰箱门把大象放进去关闭冰箱门

钩子方法

在模板方法模式的父类中,我们可以定义一个方法,它默认不做任何事情,子类可以视情况要不要覆盖,该方法称为"钩子"。

代码

上述案例把猪和大象放入了冰箱,此时,我需要看一下它们的状况,并且不关冰箱门,步骤将忽略第二步和第三步

冰箱抽象类

/** * 冰箱抽象类 * * @author Api * @DATA 2020/3/24 1:08 */public abstract class Refrigerator {    //把物品放入冰箱仅需要三步,第一步打开冰箱门,第二步把物品放进去,第三步关闭冰箱门    //必须定义为final,不允许子类进行重写    final void operating() {        openDoor();        putInto();        if (hook()) {            close();        }    }    //第一步打开冰箱门    private void openDoor() {        System.out.println("打开冰箱门");    }    //第二步把物品放入进冰箱    abstract void putInto();    //第三步关闭冰箱门    private void close() {        System.out.println("关闭冰箱门");    }    //钩子方法,决定是否关闭冰箱门    public boolean hook() {        return true;    }}

具体的实现子类

/** * 大象,具体的实现子类 * * @author Api * @DATA 2020/3/24 1:07 */public class Elephant extends Refrigerator {    @Override    void putInto() {        System.out.println("把大象放进去");    }}

具体的实现子类

/** * 猪,具体的实现子类 * * @author Api * @DATA 2020/3/24 1:07 */public class Pig extends Refrigerator {    @Override    void putInto() {        System.out.println("把猪放进去");    }}

具体的实现子类

/** * 打卡冰箱门,不干任何事 * @author Api * @DATA 2020/3/24 1:31 */public class Watch extends Refrigerator {    //空实现    @Override    void putInto() {    }    @Override    public boolean hook() {        return false;    }}

测试类

/** * 测试类 * * @author Api * @DATA 2020/3/24 1:07 */public class Client {    public static void main(String[] args) {        Refrigerator pig = new Pig();        pig.operating();        System.out.println("----------------------------------");        Refrigerator elephant = new Elephant();        elephant.operating();        System.out.println("----------------------------------");        //仅打开冰箱门,不放事物,不关冰箱门        Refrigerator watch = new Watch();        watch.operating();    }}

执行结果

打开冰箱门把猪放进去关闭冰箱门----------------------------------打开冰箱门把大象放进去关闭冰箱门----------------------------------打开冰箱门

优缺点

优点

1.扩展性好,对不变的代码进行封装,对可变的进行扩展;

2.可维护性好,因为将公共代码进行了提取,使用的时候直接调用即可。

缺点

每一个不同的实现都需要一个子类来实现,导致类的个数增加,会使系统变得复杂。

使用场景

1.有多个子类共有逻辑相同的方法;

2.重要的、复杂的方法,可以考虑作为模板方法。

注意事项

为防止恶意操作,一般模板方法都加上 final 关键词!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值