走,去出个差!模板方法模式(设计模式一)

发布于 2021-09-27 09:23

为什么开这个专题呢?相信很多小伙伴都有这样的体验:设计模式学了忘,忘了学,反反复复。

自己也踩过坑,有同样经历,后面回家跪榴莲时灵光一闪:如果把设计模式都类比成真实的场景会怎么样?


就像今天的主角—模板方法模式,以后一提起模板方法模式脑子里就闪过:害!模板方法模式,很简单啊,就是出差

国际惯例,先上概念:

模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤的实现延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中某些步骤的具体实现。

模板方法模式的核心就是抽离算法骨架和去重。OO的设计原则之一就是分离可变和不变,我们把不变的部分提取出来并放到超类中让所有子类共享其行为,同时我们把可变部分的具体实现延迟到子类中,让子类来自行决定如何实现。

有点抽象,但仔细琢磨会发现,上面这段话描述的不就是出差么:

  1. 定义一个算法的骨架 — 制定出差流程(申请、出发、工作、返回、报销)

  2. 不改变算法结构 —  流程一旦制定,不能随意更改

  3. 重新定义算法中某些步骤的具体实现 —  出行时可以选择高铁,也可以选择飞机

出差模板类(父类):

//出差模板类public abstract class BusinessTravel {    //制定出差流程(算法骨架),作为公司制度(模板),不轻易改变    //出差流程是固定,所以应该放到父类    public void travel() {        apply();         //申请        go();            //出发        work();          //工作        back();          //返程        reimburse();     //报销    }    //申请环节大家都是一样,所以直接在父类实现    protected void apply() {        System.out.println("出差申请");    }        //出发的时候每个人可以选择不同的交通方式,因此实现要放在子类    protected abstract void go();    //每个人出差工作内容也不一样,只能子类自己实现    protected abstract void work();    //和出发同理,可以选择不同交通方式,子类实现    protected abstract void back();    //报销流程都是一样的,父类直接实现    protected void reimburse() {        System.out.println("费用报销");    }}

张三出差(子类):

//张三出差public class ZhangsanTravel extends BusinessTravel {    @Override    protected void go() {        System.out.println("张三go-坐飞机");    }    @Override    protected void work() {        System.out.println("张三work-采购电脑");    }    @Override    protected void back() {        System.out.println("张三back-坐高铁");    }}

李四出差(子类):

//李四出差public class LisiTravel extends BusinessTravel {    @Override    protected void go() {        System.out.println("李四go-坐大巴");    }    @Override    protected void work() {        System.out.println("李四work-拜访客户");    }    @Override    protected void back() {        System.out.println("李四back-打车");    }}

客户端代码:

BusinessTravel zhangsanTravel= new ZhangsanTravel();zhangsanTravel.travel();System.out.println("-------------------分割线-----------------")BusinessTravel lisiTravel = new LisiTravel();lisiTravel.travel();

输出:

出差申请张三go-坐飞机张三work-采购电脑张三back-坐高铁费用报销-------------------分割线-----------------出差申请李四go-坐大巴李四work-拜访客户李四back-打车费用报销

可以看到,张三、李四两个人出差流程都是固定的(模板方法模式的核心,体会模板两个字),但在来回出行方式选择和具体工作上两个人是不一样的(子类可以自定义某个流程内部的实现细节,但没有权利更改流程

UML:

写到这里,有小伙伴可能会问,讲了这么多,这玩意儿什么时候用?

使用场景:

当我们要做的事情它的整个流程是固定(出差)的,但是个别环节上会出现不同的情况(高铁、飞机),我们可以考虑用模板方法模式来处理。

模板方法模式,就是出差!

本文来自网络或网友投稿,如有侵犯您的权益,请发邮件至:aisoutu@outlook.com 我们将第一时间删除。

相关素材