设计模式 - 模板方法模式,就该这样学!

目录

一、行为型模式

一句话概括行为型模式

1.1、模板方法模式

1.1.1、概念

1.1.2、案例实现

1.1.3、案例实现(项目实战)

1.1.4、优缺点

1.1.5、使用场景


一、行为型模式


一句话概括行为型模式

行为型模式:类或对象间如何交互、如何划分职责,从而更好的完成任务.

1.1、模板方法模式

1.1.1、概念

在一个算法骨架中,将某些算法的步骤延迟倒子类中,使得这些算法的可以根据具体的环境实现.

这就像是,我们在设计一个程序的时候经常可能会遇到这种情况:“设计了一个算法步骤,确定了这些步骤的执行顺序,但其中某些步骤还是未知,需要根据具体的业务情况而定”,此时就可以使用模板方法模式,使其放到子类实现.

例如,炒菜的步骤时固定的,分为倒油、热油、倒入要炒食物、倒调料、翻炒这几个步骤,其中 倒油、热油、翻炒这几个步骤是固定的,而炒什么食物 和 倒调料 都是要根据情况而定的.

模板方法模式包含角色:

  • 抽象类:给出一套算法的具体实现和执行顺序,其中包含一些在子类中实现的抽象方法.
  • 具体子类:实现抽象类中定义的抽象方法,他们也是算法执行逻辑的组成步骤.

1.1.2、案例实现

例如上述炒菜案例.

/**
 * 抽象类: 做菜类
 */
public abstract class DoCooking {

    public void doCooking() {
        //1.倒油
        pourOil();
        //2.热油
        hotOil();
        //3.倒食物
        pourFood();
        //4.添加调料
        addSeasoning();
        //5.翻炒
        fry();
    }

    private void pourOil() {
        System.out.println("倒油");
    }

    private void hotOil() {
        System.out.println("热油");
    }

    /**
     * 添加食物
     */
    protected abstract void pourFood();

    /**
     * 添加调料
     */
    protected abstract void addSeasoning();

    private void fry() {
        System.out.println("翻炒");
    }



}
/**
 * 具体子类: 处理鸡蛋
 */
public class HandlerEgg extends DoCooking {

    @Override
    protected void pourFood() {
        System.out.println("将鸡蛋下锅");
    }

    @Override
    protected void addSeasoning() {
        System.out.println("添加酱油");
    }

}
/**
 * 具体子类: 处理米饭
 */
public class HandlerRice extends DoCooking {

    @Override
    protected void pourFood() {
        System.out.println("将米饭下锅");
    }

    @Override
    protected void addSeasoning() {
        System.out.println("添加葱花");
    }

}
public class Client {

    public static void main(String[] args) {
        //1.炒鸡蛋
        HandlerEgg egg = new HandlerEgg();
        egg.doCooking();
        System.out.println("===================");
        //2.炒米饭
        HandlerRice rice = new HandlerRice();
        rice.doCooking();
    }

}

执行结果如下:

1.1.3、案例实现(项目实战)

以专辑信息处理流程为例,我们可以使用模板方法模式来定义一个通用的专辑处理流程.

  • 公共的逻辑:验证、记录日志等.  
  • 抽象逻辑:专辑的相关操作,如新增专辑、修改专辑.
data class Album (
    var title: String,
    var content: String,
)

abstract class AlbumProcessor {

    //模板方法,定义了专辑处理的算法骨架
    fun processAlbum(album: Album) {
        valid(album) //验证专辑有效性
        logStart(album) //记录开始处理日志
        doProcess(album) //执行具体的专辑处理逻辑
        logEnd(album) //记录结束处理日志
    }


    private fun valid(album: Album) {
        // 校验专辑标题、内容、图片是否合法
        println("Valid album ......")
    }

    private fun logStart(album: Album) {
        //记录专辑处理开始的日志
        println("[album title: ${album.title}] log start....")
    }

    private fun logEnd(album: Album) {
        //记录专辑处理结束的日志
        println("[album title: ${album.title}] log end")
    }

    //抽象方法,由子类实现专辑的具体处理逻辑
    protected abstract fun doProcess(album: Album)

}

//专辑创建处理器
class AlbumCreateProcessor: AlbumProcessor() {

    override fun doProcess(album: Album) {
        //保存专辑到数据库
        println("save to db")
    }

}

//专辑修改处理器
class AlbumEditProcessor: AlbumProcessor() {

    override fun doProcess(album: Album) {
        //更新专辑到数据库
        println("update to db")
    }

}

使用实例如下

fun main() {
    val album = Album(
        title = "Home|Gradle",
        content = "Build better software, faster. The leading software platform for improving developer productivity. Now supporting Maven, Bazel, sbt, and Gradle build systems."
    )

    //创建专辑
    val createProcessor = AlbumCreateProcessor()
    createProcessor.processAlbum(album)

    println("=========================================")

    //修改专辑
    album.title = "Maven Good"
    val editProcessor = AlbumEditProcessor()
    editProcessor.processAlbum(album)
}

运行结果如下:

1.1.4、优缺点

优点:

提高代码复用性:将相同代码放到抽象的父类中,不同实现放到不同子类中.

符合开闭原则:将来如果增加一个相关业务吗,只需要扩展实现一个子类,无需修改原有代码.

缺点:

增加系统复杂度:每一个不同实现都需要定义一个子类,会导致类的数量增加,系统更加庞大.

1.1.5、使用场景

  1. 算法的整体步骤固定,只有个别容易改变.
  2. 需要通过子类来决定父类算法中的某步骤的具体实现.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈亦康

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值