一篇打通架构设计,Java设计模式9,模板方法模式

在这里插入图片描述

一、模板方法模式

模板方法模式,在一个抽象类公开定义了执行它的方法的模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。

简单说,就是定义一个操作的算法骨架,而将一些步骤的实现延迟到子类中,使得子类可以不改变一个算法的结构就可以重新定义该算法的某些步骤。

二、模板方法模式的结构

抽象类WorkDay:定义一个模板方法work(),定义了顶级逻辑的骨架,就是一个顺序的流程,包含若干个抽象方法,推迟到子类实现。

子类将重写这些抽象方法吃早饭eat()、早会earlyMeeting()、工作计划workPlan()、摸鱼fish(),具体实现骨架的流程。

三、模板方法模式的优缺点

1、优点

  1. 模板方法模式通过把不变的行为搬移到父类,去除了子类中的重复代码。
  2. 子类实现算法的某些细节,有助于算法的扩展。
  3. 通过一个父类调用子类实现的操作,通过子类扩展增加新的行为,符合“开放-封闭原则”。

2、缺点

按照设计习惯,抽象类负责声明最抽象、最一般的事物属性和方法,实现类负责完成具体的事务属性和方法,但是模板方式正好相反,子类执行的结果影响了父类的结果,会增加代码阅读的难度。

四、模板方法模式的使用场景

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

2、重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现。

3、重构时,模板方法是一个经常使用的方法,把相同的代码抽取到父类中,然后通过构造函数约束其行为。

五、通过模板方法模式实现 抽象类WorkDay

1、顶级抽象类

package com.guor.template;

/**
 * 程序员的一天
 */
public abstract class WorkDay {
    
    

    String name;   // 姓名
    String job;  // 工作

    public WorkDay(String name, String job) {
    
    
        this.name = name;
        this.job = job;
    }

    final void work() {
    
    

        // 吃早餐
        eat();

        // 早会
        String workContent = earlyMeeting();

        // 根据早会内容制定工作计划
        boolean flag = workPlan(workContent);

        // 没有工作那就摸鱼喽
        if(true == flag){
    
    
            fish();
        }
    }

    /**
     * 吃早餐
     */
    abstract void eat();

    /**
     * 早会
     *
     * @return 工作内容
     */
    abstract String earlyMeeting();

    /**
     * 工作计划
     *
     * @param workContent 工作内容
     * @return 是否摸鱼
     */
    abstract boolean workPlan(String workContent);

    /**
     * 摸鱼
     */
    abstract void fish();
}

2、项目经理的一天

package com.guor.template;

/**
 * 项目经理
 */
public class ProjectManager extends WorkDay{
    
    

    public ProjectManager(String name, String job) {
    
    
        super(name, job);
    }

    @Override
    void eat() {
    
    
        System.out.println(name + "哪有时间吃饭");
    }

    @Override
    String earlyMeeting() {
    
    
        System.out.println(name + "的早会内容 --> " + job);
        // 写周报、工作总结、项目计划书、投标文档...
        return job;
    }

    @Override
    boolean workPlan(String workContent) {
    
    
        System.out.println(name + "工作计划:一些细思极恐的工作细节");
        return true;
    }

    @Override
    void fish() {
    
    
        System.out.println(name + "摸鱼时光:哪有时间摸鱼,操");
    }
}

3、程序员的一天

package com.guor.template;

public class Programmer extends WorkDay {
    
    

    public Programmer(String name, String job) {
    
    
        super(name, job);
    }

    @Override
    void eat() {
    
    
        System.out.println(name + " --> 吃包子喝豆浆");
    }

    @Override
    String earlyMeeting() {
    
    
        System.out.println(name + "的早会内容 --> " + job);
        return job;
    }

    @Override
    boolean workPlan(String workContent) {
    
    
        if(job.equals(workContent)){
    
    
            System.out.println(name+"的工作计划 --> "+job);
            return true;
        }
        return false;
    }

    @Override
    void fish() {
    
    
        System.out.println(name + "的摸鱼时光:看哪吒博客");
    }
}

4、女朋友的一天

package com.guor.template;

/**
 * 女朋友
 */
public class GirlFriends extends WorkDay{
    
    

    public GirlFriends(String name, String job) {
    
    
        super(name, job);
    }

    @Override
    void eat() {
    
    
        System.out.println(name + " -- 豆浆,糖酥藕片,丸子,干果仁,烤麻花,水果");
    }

    @Override
    String earlyMeeting() {
    
    
        // 只负责美,哪用开会
        System.out.println(name + "的早会内容 --> " + job);
        return "";
    }

    /**
     * 女朋友只负责美,没有工作
     */
    @Override
    boolean workPlan(String workContent) {
    
    
        System.out.println(name + "只负责美,没有工作");
        return true;
    }

    @Override
    void fish() {
    
    
        System.out.println(name + "每天除了摸鱼,还能干什么");
    }
}

5、测试类

public static void main(String[] args) {
    
    
    GirlFriends girlFriends = new GirlFriends("云韵","只负责美,没有工作");
    girlFriends.work();

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

    Programmer programmer = new Programmer("程序员","增删改查");
    programmer.work();

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

    ProjectManager projectManager = new ProjectManager("项目经理","写周报、工作总结、项目计划书、投标文档...");
    projectManager.work();
}

6、控制台显示

在这里插入图片描述

六、总结

通过上面的代码,可以清晰的看到模板方法模式的核心就是

  1. 定义一个抽象类,定义一个final的流程骨架方法,定义若干个抽象的方法;
  2. 定义子类去继承这个抽象类,根据实际的业务逻辑重写其中的抽象方法;

子类不用关心具体的执行逻辑,都是按照统一的流程去执行。类的继承者只需要关心具体的业务逻辑即可。

很多人觉得设计模式很简单,但是,能够熟练的将设计模式应用在自己的项目中,将各模块、功能规划的井井有条,运用的炉火纯青、恰到好处,真的很难。反复阅读,仔细体会。

设计模式系列文章:

java设计模式1,单一职责原则

java设计模式2,开闭原则

java设计模式3,里氏替换原则

java设计模式4,不要和陌生人说话

java设计模式5,接口隔离原则

Java设计模式6,依赖倒置原则

java设计模式7,工厂方法模式

Java设计模式8,校验、审批流程改善神器,责任链模式

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/guorui_java/article/details/126374557