栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java设计模式之模板

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java设计模式之模板

背景

按理说如果被人写的好,那我还写个啥子?没啥,就是感觉自己写一遍能记得更清楚。
模板的定义,大概就是某件事情,大家大部分步骤是一样的,甚至某些步骤的做法是一模一样的。这时候就有人把这个事情抽象出一个模板来了,方便后面的人按照模板去完成。

定义一个操作中的算法骨架,而将一些实现步骤延迟到子类中。它使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。它的要义就是定义算法骨架,让子类自己实现。

情景

比方新人入职步骤:交必要的入职材料给hr(入职流程审核需要),入职体检,去公司办理入职。

package com.aliyu.learn.pattern.template;


public abstract class EntryTemplate {

    
    protected String personName;

    public EntryTemplate(String personName) {
        this.personName = personName;
    }

    
    protected abstract void uploadData();

    
    protected abstract void checkBody();

    
    protected abstract void checkIn();

    
    public final void CheckInStep(){
        uploadData();
        checkBody();
        checkIn();
    }



}

ps:公共的步骤逻辑在抽象类中实现(CheckInStep),并用final修饰,不让子类修改。非公共的逻辑抽象为抽象方法,用protected修饰,保证只能由子类自己去实现。

模拟一个张三的模板:

package com.aliyu.learn.pattern.template;


public class EntryOne extends EntryTemplate{
    
    public EntryOne(String personName) {
        super(personName);
    }

    @Override
    protected void uploadData() {
        System.out.println("新人张三上传文档");
    }

    @Override
    protected void checkBody() {
        System.out.println("张三入职体检");
    }

    @Override
    protected void checkIn() {
        System.out.println("张三公司报道");
    }
}

李四的模板:

package com.aliyu.learn.pattern.template;


public class EntryLi extends EntryTemplate{

    public EntryLi(String personName) {
        super(personName);
    }

    @Override
    protected void uploadData() {
        System.out.println("李四上传文档");
    }

    @Override
    protected void checkBody() {
        System.out.println("李四入职体检");
    }

    @Override
    protected void checkIn() {
        System.out.println("李四公司报道");
    }
}

测试张三、李四按照模板进行“入职”:

package com.aliyu.learn.pattern.template;


public class TestTemplate {

    public static void main(String[] args) {

        EntryLi entryLi = new EntryLi("李四");
        entryLi.checkInStep();

        EntryZhang entryZhang = new EntryZhang("张三");
        entryZhang.checkInStep();

    }
}

钩子方法

为啥叫钩子方法?不晓得。它的由来是,比方上面的三个步骤中,如果你有一年内体检报告,那么就没必要体检了。但是这个步骤可能是少数情况,你又不想为了这个重新写一个模板。当然你可以说不体检的人,实现体检方法时,啥也不做就好。这种写法是不优雅的,也容易造成误解。有就是有,没有就是没有。你实现了“体检”方法,却啥也不做?
实现代码:

package com.aliyu.learn.pattern.template;


public abstract class EntryTemplate {

    
    protected String personName;

    public EntryTemplate(String personName) {
        this.personName = personName;
    }

    
    protected abstract void uploadData();

    
    protected abstract void checkBody();

    
    protected abstract void checkIn();

    
    protected boolean isCheckBody(){
        return true;
    }

    
    public final void checkInStep(){
        System.out.println("入职人:" + personName);
        uploadData();
        //是否执行体检交由"钩子方法"判断,而钩子方法可以被子类重写
        if(this.isCheckBody()){
            checkBody();
        }
        checkIn();
    }



}

ps:注意到,它加了一个钩子方法“isCheckBody”,默认返回true。
同时骨架方法“checkInStep”中的加了一个判断,将是否体检交由钩子方法判断。而钩子方法可以被子类重写,也就是子类可以自行决定是否参加体检。

不参加体检的王五:

package com.aliyu.learn.pattern.template;


public class EntryWang extends EntryTemplate{

    private boolean checkBodyFlag = true;

    public EntryWang(String personName) {
        super(personName);
    }

    public EntryWang(String personName, boolean checkBodyFlag) {
        super(personName);
        this.checkBodyFlag = checkBodyFlag;
    }

    @Override
    protected void uploadData() {
        System.out.println("王五上传文档");
    }

    @Override
    protected void checkBody() {
        System.out.println("王五入职体检");
    }

    @Override
    protected void checkIn() {
        System.out.println("王五公司报道");
    }

    @Override
    protected boolean isCheckBody(){
        return this.checkBodyFlag;
    }
}

ps:加了一个属性“是否体检”和对应的构造方法,使得王五初始化的时候就可以指定自己是否参加体检。

测试代码:

package com.aliyu.learn.pattern.template;


public class TestHookTemplate {

    public static void main(String[] args) {

        EntryLi entryLi = new EntryLi("李四");
        entryLi.checkInStep();

        EntryWang entryWang = new EntryWang("王五", false);
        entryWang.checkInStep();

    }
}


可以看到,王五确实没有体检了。

其他
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/340301.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号