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

【JavaSE】Java设计模式详解(二)抽象模板模式

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

【JavaSE】Java设计模式详解(二)抽象模板模式

 个人主页:Nezuko627的博客主页 欢迎来访~~~
❤️ 支持我: 点赞  收藏 落关注
 格言:立志做一个有思想的程序员 
 作者介绍:本人本科软件工程在读,博客及技术将主要涉及JavaSE、JavaEE、MySQL、SpringBoot、算法等。专栏内容长期更新,如有错误,欢迎评论区或者私信指正!谢谢大家的支持~~~

本篇学习目标:

  • ⭐️ 了解什么是抽象模板模式;
  • ⭐️ 了解模板模式的设计过程;
  • ⭐️ 体会抽象模板设计模式的好处。

本文来自专栏:JavaSE系列专题知识及项目 欢迎点击支持订阅专栏 ❤️

文章目录
  • 1 问题引入
  • 2 初步优化(每个类内部)
  • 3 抽象模板设计
  • 写在最后


1 问题引入

✈️ 老套路啦!我们先来看一个需求:

有多个类,假设有三个:小学生类Pupil、中学生类MStudent、大学生类CStudent ,其中每个类都有不同的 homework() 方法,要求你统计各自完成作业需要的时间。

Tips: 在实现需求时,我们假设小学生、中学生、大学生完成作业的时间是依次增加的,将其作业的任务设置成一个方法 homework,用于完成作业并计算完成作业的时间。

 参考代码:

⭐️ Pupil类:

class Pupil{
    private String name = "小学生";
    public String getName(){
        return this.name;
    }
    // 完成作业
    public void homework(){
        long start = System.currentTimeMillis();
        long time = 0;
        for (int i = 0; i < 100000; i++) {
            time += i;
        }
        long end = System.currentTimeMillis();
        System.out.println(getName() + "完成作业用时:" + (end-start) + "h");
    }
}

⭐️ MStudent类:

class MStudent{
    private String name = "中学生";
    public String getName(){
        return this.name;
    }
    // 完成作业
    public void homework(){
        long start = System.currentTimeMillis();
        long time = 0;
        for (int i = 0; i < 9000000; i++) {
            time += i;
        }
        long end = System.currentTimeMillis();
        System.out.println(getName() + "完成作业用时:" + (end-start) + "h");
    }
}

⭐️ CStudent类:

class CStudent{
    private String name = "大学生";
    public String getName(){
        return this.name;
    }
    // 完成作业
    public void homework(){
        long start = System.currentTimeMillis();
        long time = 0;
        for (int i = 0; i < 90000000; i++) {
            time += i;
        }
        long end = System.currentTimeMillis();
        System.out.println(getName() + "完成作业用时:" + (end-start) + "h");
    }
}

⭐️ 测试类:

public class TestTemplate {
    public static void main(String[] args) {
        new Pupil().homework();  // 小学生
        new MStudent().homework();  // 中学生
        new CStudent().homework();  // 大学生
    }
}

 实现结果:

小学生完成作业用时:1h
中学生完成作业用时:5h
大学生完成作业用时:26h

好啦,到这里我们已经实现了需求,但是,小伙伴们,有没有发现一个问题?我们来比较一下小学生、中学生、大学生三个类中的 homework() 方法就会发现: 代码的冗余度过高,在方法内有很多重复的步骤,代码的复用性不强! 怎么解决呢?别急继续往下看~


2 初步优化(每个类内部)

 我们可以从 homework() 方法中将重复的部分单独提出来,设置成一个 computingTime() 方法,用于计算作业完成所需要的时间,具体见下图(以大学生类为例,其他两个类进行一样的操作):

⭐️ Star 1: 将公共部分提取成一个方法


⭐️ Star 2: 其余部分在该方法中调用

 优化后的代码如下:

public class TestTemplate {
    public static void main(String[] args) {
        new Pupil().computingTime();  // 小学生
        new MStudent().computingTime();  // 中学生
        new CStudent().computingTime();  // 大学生
    }
}

class Pupil{
    private String name = "小学生";
    public String getName(){
        return this.name;
    }
    // 计算作业完成所需要的时间
    public void computingTime(){
        long start = System.currentTimeMillis();
        homework(); // 写作业
        long end = System.currentTimeMillis();
        System.out.println(getName() + "完成作业用时:" + (end-start) + "h");
    }
    // 完成作业
    public void homework(){
        long time = 0;
        for (int i = 0; i < 100000; i++) {
            time += i;
        }
    }
}

class MStudent{
    private String name = "中学生";
    public String getName(){
        return this.name;
    }
    // 计算作业完成所需要的时间
    public void computingTime(){
        long start = System.currentTimeMillis();
        homework(); // 写作业
        long end = System.currentTimeMillis();
        System.out.println(getName() + "完成作业用时:" + (end-start) + "h");
    }
    // 完成作业
    public void homework(){
        long time = 0;
        for (int i = 0; i < 9000000; i++) {
            time += i;
        }
    }
}

class CStudent{
    private String name = "大学生";
    public String getName(){
        return this.name;
    }
    // 计算作业完成所需要的时间
    public void computingTime(){
        long start = System.currentTimeMillis();
        homework(); // 写作业
        long end = System.currentTimeMillis();
        System.out.println(getName() + "完成作业用时:" + (end-start) + "h");
    }
    // 完成作业
    public void homework(){
        long time = 0;
        for (int i = 0; i < 90000000; i++) {
            time += i;
        }
    }
}

 现在,我们已经成功将方法中的公共部分给提取出来,单独设置成了 computingTime() 方法,但是,很快我们又发现了问题:一共有三个类,每个类都需要提取一次,设置出一个单独的方法,还是过于繁琐,需要进一步优化,我们接着往下看。


3 抽象模板设计

 既然重复,我们为何不 尝试将重复的部分提取到一个模板类里,让这三个类继承 呢?这样每个类都不需要声明该方法,就可以使用啦!具体如下图:

 在这里,我们将三个类中共有的computingTime() 方法提取到 Template类作为模板,让子类继承。并且,将三个类中不同的部分 homework类 在父类中抽象,子类实现。在实际调用中,由于动态绑定机制,使用的则是 new 创建的对象所绑定的方法,先是子类,若子类不存在该方法再访问父类,这点在之前的文章讲过,这里直接上传送门哈!
❤️ 【JavaSE】面向对象之多态、向上转型与向下转型
具体方式如下:


 优化后的完整代码:

public class TestTemplate {
    public static void main(String[] args) {
        new Pupil().computingTime();  // 小学生
        new MStudent().computingTime();  // 中学生
        new CStudent().computingTime();  // 大学生
    }
}

// 模板类
abstract class Template{
    private String name;
    public String getName(){
        return this.name;
    }
    // 计算作业完成所需要的时间
    public void computingTime(){
        long start = System.currentTimeMillis();
        homework(); // 写作业
        long end = System.currentTimeMillis();
        System.out.println(getName() + "完成作业用时:" + (end-start) + "h");
    }
    abstract void homework();
}

class Pupil extends Template{
    private String name = "小学生";
    public String getName(){
        return this.name;
    }
    // 完成作业
    public void homework(){
        long time = 0;
        for (int i = 0; i < 100000; i++) {
            time += i;
        }
    }
}

class MStudent extends Template{
    private String name = "中学生";
    public String getName(){
        return this.name;
    }
    // 完成作业
    public void homework(){
        long time = 0;
        for (int i = 0; i < 9000000; i++) {
            time += i;
        }
    }
}

class CStudent extends Template{
    private String name = "大学生";
    public String getName(){
        return this.name;
    }
    // 完成作业
    public void homework(){
        long time = 0;
        for (int i = 0; i < 90000000; i++) {
            time += i;
        }
    }
}

 实现结果:

小学生完成作业用时:1h
中学生完成作业用时:4h
大学生完成作业用时:26h


写在最后

以上便是本文的全部内容啦,后续内容将会持续免费更新,如果文章对你有所帮助,麻烦动动小手点个赞 + 关注,非常感谢 ❤️ ❤️ ❤️ !
如果有问题,欢迎私信或者评论区!

共勉:“你间歇性的努力和蒙混过日子,都是对之前努力的清零。”

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

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

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