设计模式课程 设计模式精讲 17-2 模板方法模式coding

1    代码演练

1.1  代码演练1

1.2  代码演练2(后端课程子类运用钩子方法,加入写手记的方法)

1.3  代码演练3(前端有多个子类,有得需要写手记,有得不需要写,如何实现?)

1    代码演练
1.1  代码演练1

目的:

木木网制作课程视频父类,前端课程子类和设计模式子类。父类需要制作PPT,制作视频,制作手记,包装课程四个部分,且步骤基本一致,其中制作PPT和制作视频都一致,前端子类和后端子类包装课程方法不一样。

uml类图:

测试类:

package com.geely.design.pattern.behavioral.templatemethod;

public class Test {
    public static void main(String [] args){

        System.out.println("=======================后端课程开始");
        ACourse aCourse1 = new DesignPatternCourse();
        aCourse1.makeCourse();
        System.out.println("=======================后端课程结束");


        System.out.println("=======================前端课程开始");
        ACourse aCourse2 = new FECourse();
        aCourse2.makeCourse();
        System.out.println("=======================前端课程结束");
    }
}

抽象课程父类:

package com.geely.design.pattern.behavioral.templatemethod;

/**
 * 制作抽象类 课程类,用于被其他类继承
 */
public abstract class ACourse {

    /**
     * 整合课程 的方法,
     * 该流程是固定的,子类不能重写
     */
    protected final void makeCourse(){
        makePPT();
        makeVideo();
        if(needMakeArticle()){
            makeArticle();
        }
        packageCourse();
    }
    /**
     * 制作PPT 方法
     * 目的:如果想要每个子类都不能重写该方法,就用final修饰
     * 原因:每个子类都必须有制作PPT的方法
     */
    final void makePPT(){
        System.out.println("开始制作PPT");
    }

    /**
     * 同上
     */
    final void makeVideo(){
        System.out.println("制作课程视频");
    }

    /**
     * 制作手记方法
     * 该方法不可被重写
     * 有的课程需要制作,有的课程不需要
     */
    final void makeArticle(){
        System.out.println("编写手记");
    }

    /**
     * 添加钩子方法
     * 该方法可被子类重写,用于判断子类是否需要制作手记
     * @return
     */
    protected boolean needMakeArticle(){
        return false;
    }

    /**
     * 包装课程方法,
     * 目的:不同的课程,包装的素材也不一样,所以声明抽象的,子类可以重写
     */
    abstract void packageCourse();
}

前端子类:

package com.geely.design.pattern.behavioral.templatemethod;

public class FECourse extends ACourse{
    /**
     * 不同子类实现不同包装方法
     */
    @Override
    void packageCourse() {
        System.out.println("提供课程前端代码");
        System.out.println("提供课程图片素材");
    }
}

后端子类:

package com.geely.design.pattern.behavioral.templatemethod;

/**
 * 设计模式课程,
 * 业务场景:不用编写手记
 */
public class DesignPatternCourse extends ACourse{
    /**
     * 不同子类实现不同包装方法
     */
    @Override
    void packageCourse() {
        System.out.println("后端包装方法实现");
    }
}

打印结果:

=======================后端课程开始
开始制作PPT
制作课程视频
后端包装方法实现
=======================后端课程结束
=======================前端课程开始
开始制作PPT
制作课程视频
提供课程前端代码
提供课程图片素材
=======================前端课程结束

Process finished with exit code 0
1.2  代码演练2(后端课程子类运用钩子方法,加入写手记的方法)

重点:

后端课程子类

后端课程子类:

package com.geely.design.pattern.behavioral.templatemethod;

/**
 * 设计模式课程,
 * 业务场景:不用编写手记
 */
public class DesignPatternCourse extends ACourse{
    /**
     * 钩子方法,后端课程加入编写手记方法
     * @return
     */
    @Override
    protected boolean needMakeArticle() {
        return true;
    }

    /**
     * 不同子类实现不同包装方法
     */
    @Override
    void packageCourse() {
        System.out.println("后端包装方法实现");
    }
}

前端课程子类:

package com.geely.design.pattern.behavioral.templatemethod;

public class FECourse extends ACourse{
    /**
     * 不同子类实现不同包装方法
     */
    @Override
    void packageCourse() {
        System.out.println("提供课程前端代码");
        System.out.println("提供课程图片素材");
    }
}

课程类:

package com.geely.design.pattern.behavioral.templatemethod;

/**
 * 制作抽象类 课程类,用于被其他类继承
 */
public abstract class ACourse {

    /**
     * 整合课程 的方法,
     * 该流程是固定的,子类不能重写
     */
    protected final void makeCourse(){
        makePPT();
        makeVideo();
        if(needMakeArticle()){
            makeArticle();
        }
        packageCourse();
    }
    /**
     * 制作PPT 方法
     * 目的:如果想要每个子类都不能重写该方法,就用final修饰
     * 原因:每个子类都必须有制作PPT的方法
     */
    final void makePPT(){
        System.out.println("开始制作PPT");
    }

    /**
     * 同上
     */
    final void makeVideo(){
        System.out.println("制作课程视频");
    }

    /**
     * 制作手记方法
     * 该方法不可被重写
     * 有的课程需要制作,有的课程不需要
     */
    final void makeArticle(){
        System.out.println("编写手记");
    }

    /**
     * 添加钩子方法
     * 该方法可被子类重写,用于判断子类是否需要制作手记
     * @return
     */
    protected boolean needMakeArticle(){
        return false;
    }

    /**
     * 包装课程方法,
     * 目的:不同的课程,包装的素材也不一样,所以声明抽象的,子类可以重写
     */
    abstract void packageCourse();
}

测试类:

package com.geely.design.pattern.behavioral.templatemethod;

public class Test {
    public static void main(String [] args){

        System.out.println("=======================后端课程开始");
        ACourse aCourse1 = new DesignPatternCourse();
        aCourse1.makeCourse();
        System.out.println("=======================后端课程结束");


        System.out.println("=======================前端课程开始");
        ACourse aCourse2 = new FECourse();
        aCourse2.makeCourse();
        System.out.println("=======================前端课程结束");
    }
}

打印日志:

=======================后端课程开始
开始制作PPT
制作课程视频
编写手记
后端包装方法实现
=======================后端课程结束
=======================前端课程开始
开始制作PPT
制作课程视频
提供课程前端代码
提供课程图片素材
=======================前端课程结束

Process finished with exit code 0
1.3  代码演练3(前端有多个子类,有得需要写手记,有得不需要写,如何实现?)

解决方案:

将是否需要手记这个字段开放给应用层,这样使用起来更加灵活

uml类图:

重点看:

测试类和前端子类

测试类:

package com.geely.design.pattern.behavioral.templatemethod;

public class Test {
    public static void main(String [] args){

   /*     System.out.println("=======================后端课程开始");
        ACourse aCourse1 = new DesignPatternCourse();
        aCourse1.makeCourse();
        System.out.println("=======================后端课程结束");*/


        System.out.println("=======================前端课程开始");
        ACourse aCourse2 = new FECourse(true);
        aCourse2.makeCourse();
        System.out.println("=======================前端课程结束");

        System.out.println("=======================前端课程开始");
        ACourse aCourse3 = new FECourse(false);
        aCourse3.makeCourse();
        System.out.println("=======================前端课程结束");
    }
}

前端子类:

package com.geely.design.pattern.behavioral.templatemethod;

public class FECourse extends ACourse{
    boolean bNeedMakeArticleFlag = false;

    /**
     * 用注入的方式 将该字段传入
     * @param bNeedMakeArticleFlag
     */
    public FECourse(boolean bNeedMakeArticleFlag) {
        this.bNeedMakeArticleFlag = bNeedMakeArticleFlag;
    }

    /**
     * 不同子类实现不同包装方法
     */
    @Override
    protected boolean needMakeArticle() {
        return this.bNeedMakeArticleFlag;
    }

    @Override
    void packageCourse() {
        System.out.println("提供课程前端代码");
        System.out.println("提供课程图片素材");
    }
}

后端子类:

package com.geely.design.pattern.behavioral.templatemethod;

/**
 * 设计模式课程,
 * 业务场景:不用编写手记
 */
public class DesignPatternCourse extends ACourse{
    /**
     * 钩子方法,后端课程加入编写手记方法
     * @return
     */
    @Override
    protected boolean needMakeArticle() {
        return true;
    }

    /**
     * 不同子类实现不同包装方法
     */
    @Override
    void packageCourse() {
        System.out.println("后端包装方法实现");
    }
}

课程类:

package com.geely.design.pattern.behavioral.templatemethod;

/**
 * 制作抽象类 课程类,用于被其他类继承
 */
public abstract class ACourse {

    /**
     * 整合课程 的方法,
     * 该流程是固定的,子类不能重写
     */
    protected final void makeCourse(){
        makePPT();
        makeVideo();
        if(needMakeArticle()){
            makeArticle();
        }
        packageCourse();
    }
    /**
     * 制作PPT 方法
     * 目的:如果想要每个子类都不能重写该方法,就用final修饰
     * 原因:每个子类都必须有制作PPT的方法
     */
    final void makePPT(){
        System.out.println("开始制作PPT");
    }

    /**
     * 同上
     */
    final void makeVideo(){
        System.out.println("制作课程视频");
    }

    /**
     * 制作手记方法
     * 该方法不可被重写
     * 有的课程需要制作,有的课程不需要
     */
    final void makeArticle(){
        System.out.println("编写手记");
    }

    /**
     * 添加钩子方法
     * 该方法可被子类重写,用于判断子类是否需要制作手记
     * @return
     */
    protected boolean needMakeArticle(){
        return false;
    }

    /**
     * 包装课程方法,
     * 目的:不同的课程,包装的素材也不一样,所以声明抽象的,子类可以重写
     */
    abstract void packageCourse();
}

打印结果:

=======================前端课程开始
开始制作PPT
制作课程视频
编写手记
提供课程前端代码
提供课程图片素材
=======================前端课程结束
=======================前端课程开始
开始制作PPT
制作课程视频
提供课程前端代码
提供课程图片素材
=======================前端课程结束

Process finished with exit code 0
原文地址:https://www.cnblogs.com/1446358788-qq/p/11553619.html