设计模式-模板方法模式
本文最后更新于 1763 天前,其中的信息可能已经有所发展或是发生改变。

介绍

模板方法是一种行为类设计模式。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。

模板方法是一个定义在父类的方法(抽象类),具体实现由子类实现

优点:

1、封装不变部分,扩展可变部分。

2、提取公共代码,便于维护。

3、行为由父类控制,子类实现。

缺点:

每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。

使用场景:

1、有多个子类共有的方法,且逻辑相同。

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

注意事项:

1.为防止恶意操作,一般模板方法都加上 final 关键词,不允许被重写

2.抽象模板中的基本方法尽量设计为protected类型,符合迪米特法则,不需要暴露的属性或方法尽量不要设置为protected类型。实现类若非必要,尽量不要扩大父类中的访问权限

实现

模拟场景:

汽车都有以下步骤:启动汽车、停止汽车、响喇叭、汽车跑起来…等等

UML图:

image-20211021234031326

基础的汽车类

public abstract class Car {

    protected abstract void start();

    protected abstract void stop();

    protected abstract void alarm();

    final void run(){
        start();
        alarm();
        stop();
    }
}

宝马汽车:

public class BMWCar extends Car{

    @Override
    protected void start() {
        System.out.println("BMW发动……");

    }

    @Override
    protected void stop() {
        System.out.println("BMW停止……");
    }

    @Override
    protected void alarm() {
        System.out.println("BMW响喇叭……");
    }
}

奔驰汽车:

public class MercedesCar extends Car{

    @Override
    protected void start() {
        System.out.println("Mercedes发动……");
    }

    @Override
    protected void stop() {
        System.out.println("Mercedes停止……");
    }

    @Override
    protected void alarm() {
        System.out.println("Mercedes响喇叭……");
    }
}

测试运行:

    public static void main(String[] args) {

        Car bmw = new BMWCar();
        bmw.run();

        System.out.println("====================");

        Car mercedes = new MercedesCar();
        mercedes.run();

    }
-------------------
BMW发动……
BMW响喇叭……
BMW停止……
====================
Mercedes发动……
Mercedes响喇叭……
Mercedes停止……

拓展延申

首先不是所有的汽车都会在运行的时候响喇叭(市区禁鸣),那这个时候我们该咋办呢?

解决方案如下:

  修改 Car 添加一个是否能响喇叭的方法,让自身判断是否能响喇叭。同时子类需要增加相应的实现。

基础的汽车类

public abstract class Car {

    protected abstract void start();

    protected abstract void stop();

    protected abstract void alarm();

    protected abstract boolean isAlarm();

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

宝马汽车:

public class BMWCar extends Car{

    @Override
    protected void start() {
        System.out.println("BMW发动……");

    }

    @Override
    protected void stop() {
        System.out.println("BMW停止……");
    }

    @Override
    protected void alarm() {
        System.out.println("BMW响喇叭……");
    }

    @Override
    protected boolean isAlarm() {
        System.out.println("我不经过市区可以响喇叭....");
        return true;
    }
}

奔驰汽车:

public class MercedesCar extends Car{

    @Override
    protected void start() {
        System.out.println("Mercedes发动……");
    }

    @Override
    protected void stop() {
        System.out.println("Mercedes停止……");
    }

    @Override
    protected void alarm() {
        System.out.println("Mercedes响喇叭……");
    }

    @Override
    protected boolean isAlarm() {
        System.out.println("我天天经过市区塞车...还不可以响喇叭....");
        return false;
    }
}

测试运行:

BMW发动……
我不经过市区可以响喇叭....
BMW响喇叭……
BMW停止……
====================
Mercedes发动……
我天天经过市区塞车...还不可以响喇叭....
Mercedes停止……

延申涉及的钩子方法

  在我们的Car抽象类中isAlarm()的返回值就是影响了模板方法的执行结果,该方法就叫做钩子方法(HookMethod)。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇