java设计模式---模板方法模式

本文详细解析了Java设计模式中的模板方法模式,包括其定义、步骤及要点,并通过具体实现展示了如何使用该模式。同时,文章还介绍了模板方法模式的扩展——带钩子函数的模板方法模式,以及其在实际开发中的应用。

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

java设计模式—模板方法模式

1.定义 : 定义一个操作中算法的框架,而去将一些步骤延迟到子类实现,使得子类不改变一个算法的结构即可重定义该算法的某些特定步骤.说的有点高大上啊,简单来说是这样的,定义一个抽象类,这个类叫做抽象模板,它里面有两种方法: 1.模板方法,一般是一个具体的方法,也就是一个框架,一个算法,将其他方法进行调度,完成一些固定的逻辑. 2. 基本方法,也就是这些方法是抽象的应该由子类实现的.并且应该去让模板方法进行调度. 其他类就实现这个模板并定义一些具体的逻辑.

2.步骤及要点
1.定义一个抽象类作为具体模板,将算法调度作为一个或多个具体的实现方法定义,其他方法应由子类去实现.
2.定义具体的模板集成这个抽象模板,并完成具体的业务逻辑.

是不是很简单,是的,模板方法模式本来就不太难,它有着自己明显的特点,可能我们实际开发中用到过,但是我们不知道它是模板方法模式也有可能.

3.下面看具体实现.

(1) 通用实现(一般实现)

/**
 * 这是抽象模板类
 * @author psp
 *
 */
public abstract class Car {

     protected  abstract void start();

     protected  abstract void stop();

     protected  abstract void engineBoom();

     public final void run(){
         start();
         stop();
         engineBoom();
     }

}

/**
 * 这是一个具体的模板类
 * @author psp
 *
 */
public class Benz extends Car {

    protected void start() {
   System.out.println("奔驰车启动了.");
    }

    protected void stop() {
  System.out.println("奔驰车停止了.");
    }

    protected void engineBoom() {
         System.out.println("奔驰车鸣笛.");
    }

}

/**
 * 这是另一个具体的模板类
 * @author psp
 *
 */
public class Bmw extends Car {

    protected void start() {
   System.out.println("宝马车启动了.");
    }

    protected void stop() {
  System.out.println("宝马车停止了.");
    }

    protected void engineBoom() {
         System.out.println("宝马车鸣笛.");
    }

/**
 * 这是一个测试类
 * 
 * @author psp
 * 
 */
public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Car benz = new Benz();
        Car bmw = new Bmw();

        benz.run();
        bmw.run();
    }

}

需要注意的地方: 抽象模板类中模板方法一般设置为final类型,不允许被复写. 抽象模板类中的基本方法一般设置成protected 类型,子类尽量不要扩大其访问权限,这样也符合设计模式的迪米特法则.迪米特法则的原则是低耦合,弱耦合,又叫做最少知识原则.

模板方法实现后的优点:

  • 封装不变的部分,扩展可变部分.
  • 提取公共部分代码,便于维护
  • 行为由父类控制,子类实现

(2)模板方法模式的扩展(带钩子函数的模板方法模式)

假如: 有一天,我们发现基本方法的调用是有条件的,也就是说,某个或某几个基本方法可能需要调用,也可能不需要调用,具体要看子类是否需要,假如需要改上这么一个需求,我们怎么办呢?我们是不是要哭了,不能,自己写的代码,含着泪也要改完.(不要想歪了…)这个其实也简单,加入一个钩子函数就行了,什么是钩子函数呢,其实这个函数就像我们平常开发中用到的变量控制,或者条件控制一样,只不过封装到一个方法里面了.下面看具体实现.假如现在我们不一定需要汽车鸣笛,是否需要鸣笛看子类自己想不想,由子类自己来控制.

/**
 * 这是抽象模板类
 * 
 * @author psp
 * 
 */
public abstract class Car {

    protected abstract void start();

    protected abstract void stop();

    protected abstract void engineBoom();

    public final void run() {
        start();
        if (isAlarm()) {
            engineBoom();
        }
        stop();
    }

    /**
     * 钩子函数
     * 
     * @return 是否需要鸣笛,默认为true.
     */
    protected boolean isAlarm() {
        return true;
    }
}

/**
 * 这是一个具体的模板类
 * @author psp
 *
 */
public class Benz extends Car {

    protected void start() {
   System.out.println("奔驰车启动了.");
    }

    protected void stop() {
  System.out.println("奔驰车停止了.");
    }

    protected void engineBoom() {
         System.out.println("奔驰车鸣笛.");
    }

    /**
     * 子类重写该方法,默认需要鸣笛
     */
    protected boolean isAlarm() {
        return true;
    }
}

/**
 * 这是另一个具体的模板类
 * @author psp
 *
 */
public class Bmw extends Car {

    protected void start() {
   System.out.println("宝马车启动了.");
    }

    protected void stop() {
  System.out.println("宝马车停止了.");
    }

    protected void engineBoom() {
         System.out.println("宝马车鸣笛.");
    }

    /**
     * 子类重写该方法,默认不需要鸣笛
     */
    protected boolean isAlarm() {
        return false;
    }

}

Test 测试类不变,通过加入一个钩子函数,我们就可以完美的控制某些基本方法是否在框架方法需要执行,而且需不需要是由子类控制的,而不是父类,父类只是提供一个默认的实现,子类可以覆写并定义自己的逻辑.这就是带钩子函数的模板方法的模式.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值