IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 设计模式-模板方法模式 -> 正文阅读

[网络协议]设计模式-模板方法模式


一、什么是模板方法模式?

???? 模板方法:定义了一套流程算法骨架,将一些固定的算法由抽象类定义,可变的部分延迟到子类中实现,同时可以定义一些钩子方法控制抽象类的操作。
模式的结构
1、抽象类(模板方法、抽象方法、具体方法、钩子方法)
???? 模板方法:定义具体操作流程,按某种顺序调用抽象方法、具体方法和钩子方法。
???? 抽象方法:需要子类实现的方法。
???? 具体方法:个流程相同的方法,由抽象类统一实现的。子类可以对其进行重写。
2、具体实现类
???? 实现抽象类中的抽象方法。
???? AbstractClass为抽象类,templateMethod()为抽象方法里面调用了具体方法(specificMethod())和抽象方法(abstractMethod()),SubClass为AbstractClass的子类实现了实现了抽象方法。ClientClass为客户类用于调用抽象类的模板方法。
UML图如下:
template_method_UML
模板方法模式的优缺点
优点:
???? 1、将不变的部分封装到父类,可变部分由子类进行实现,便于子类进行扩展。
???? 2、将公用部分统一由父类实现,提高了代码的复用性。
缺点:
???? 1、每个不同的实现都要增加类的个数,增加了系统的复杂程度,也增加了代码阅读的难度。
???? 2、由于继承关系,父类增加抽象方法所有的子类都需要进行实现,所有子类都需要进行修改。

二、模板方法模式应用实例

???? 每个人的一天都是不同的,但具有相同部分例如起床、洗漱、吃早饭、完成上午的工作、午休、完成下午的工作、下班后的自由时间、晚上休息等。每天不同的地方在于上午的工作、下午的工作、下班后的自由时间所做的事情不同,其他基本是一样的。以一天为例实现一个简单的模板方法模式。
代码如下:

// 测试类
public class TestOneDay {
    public static void main(String[] args) {
        System.out.println("创建学生一天实例");
        OneDayAbstract studentDay = new StudentDay();
        System.out.println("执行学生的一天");
        studentDay.run();
        
        System.out.println("创建程序员一天实例");
        OneDayAbstract programmerDay = new ProgrammerDay();
        System.out.println("执行程序员的一天");
        programmerDay.run();
    }
}

/**
* 一天(抽象类)
*/
public abstract class OneDayAbstract {

    // 执行一天要做的事(模板方法 调用具体方法、抽象方法)
    public void run(){
        System.out.println("新的一天开始了!!!!");
        System.out.println("时间:07:00");
        up();
        System.out.println("时间:09:00");
        work1();
        System.out.println("时间:11:30");
        noonBreak();
        System.out.println("时间:13:30");
        work2();
        System.out.println("时间:18:00");
        anything();
        System.out.println("时间:23:00");
        sleep();
        System.out.println("新的一天结束了!!!!");
    }
	// 具体方法 早起做的事
    public void up(){
        System.out.println("起床!!!");
        System.out.println("洗漱!!");
        System.out.println("吃早饭!");
    }

    // 抽象方法 子类需要实现 完成上午的工作
    abstract void work1();

	// 具体方法 午休
    public void noonBreak(){
        System.out.println("午休~");
    }

    // 抽象方法 子类需要实现 完成下午的工作
    abstract void work2();

    // 抽象方法 子类需要实现 下班后可以做任意事
    abstract void anything();
	// 具体方法 一天结束休息
    public void sleep(){
        System.out.println("休息!!!!!");
    }
}

/**
* 程序员的一天
*/
public class ProgrammerDay extends OneDayAbstract {

    @Override
    void work1() {
        System.out.println("上午-敲代码!!!!");
    }

    @Override
    void work2() {
        System.out.println("下午-敲代码!!!!");
    }

    @Override
    void anything() {
        System.out.println("下班?不可能的。加班继续敲代码!!!!");
    }
}

/**
 * 学生的一天
 */
public class StudentDay extends OneDayAbstract {
    @Override
    void work1() {
        System.out.println("上数学、语文、英语课!!!");
    }

    @Override
    void work2() {
        System.out.println("上物理、化学、生物课!!!");
    }

    @Override
    void anything() {
        System.out.println("晚自习拼命做题!!!");
    }
}

执行结果如下:
程序执行结果
???? 以学生和程序员为例实现了一天的抽象类。如果需要再添加一类人的一天则只需要集成抽象类并实现抽象方法就可以完成了,提高了开发效率。

模板方法模式拓展
???? 抽象类中还有一类方法叫钩子方法,钩子方法一般是指判断的逻辑方法或者空方法由子类进行实现的,下面说明下钩子方法的使用。
一天的需求有变动,由于项目近期要上线需要赶工,程序员的午休时间取消了(程序员:mmp)。这时可以在抽象类的模板方法中增加判断逻辑。代码如下:

// 其他方法不变 只贴出了修改的方法
public abstract class OneDayAbstract {

    // 修改模板方法中逻辑 午休增加判断
    public void run(){
        System.out.println("新的一天开始了!!!!");
        System.out.println("时间:07:00");
        up();
        System.out.println("时间:09:00");
        work1();
        System.out.println("时间:11:30");
        // 判断是否需要午休
        if(haveNoonBreak()){
            noonBreak();
        }
        System.out.println("时间:13:30");
        work2();
        System.out.println("时间:18:00");
        anything();
        System.out.println("时间:23:00");
        sleep();
        System.out.println("新的一天结束了!!!!");
    }

    // 是否需要午休 默认为true 需要午休
    public boolean haveNoonBreak(){
        return true;
    }
}

/**
* 程序员的一天
*/
public class ProgrammerDay extends OneDayAbstract {

    @Override
    void work1() {
        System.out.println("上午-敲代码!!!!");
    }

    @Override
    void work2() {
        System.out.println("下午-敲代码!!!!");
    }

    @Override
    void anything() {
        System.out.println("下班?不可能的。加班继续敲代码!!!!");
    }

    // 覆盖方法 修改返回值为false 不需要午休
    @Override
    public boolean haveNoonBreak(){
        return false;
    }
}

修改后执行的结果如下:result2
增加了钩子方法后一般不会影响原有的实现类,因为钩子方法是默认实现的返回值为true。当返回值为true是模板方法的逻辑也没有发生变化,只有子类修改返回值为false时模板方法的逻辑才会发生变化。当然钩子的使用一般在程序设计时就已经添加在抽象类中了。


  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-12-14 16:19:48  更:2021-12-14 16:20:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年10日历 -2024/10/5 7:09:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码