c#设计模式-行为型模式 之 模板方法模式

news2024/11/20 20:18:35

🚀简介

        模板方法模式定义了一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。通常用于应对在开发中设计一个系统时知道了算法所需的关键步骤,而且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,或者说某些步骤的实现与具体的环境相关。

👻角色

模板方法( Template Method )模式包含以下主要角色:
  1. 抽象类(Abstract Class):负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基 本方法构成。
    1. 模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法。
    2. 基本方法:是实现算法各个步骤的方法,是模板方法的组成部分。基本方法又可以分为三 种:
      1. 抽象方法(Abstract Method) :一个抽象方法由抽象类声明、由其具体子类实现。
      2. 具体方法(Concrete Method) :一个具体方法由一个抽象类或具体类声明并实现, 其子类可以进行覆盖也可以直接继承。
      3. 钩子方法(Hook Method) :在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种。一般钩子方法是用于判断的逻辑方法,这类方法名一般为isXxx,返回值类型为boolean类型。
  2. 具体子类(Concrete Class):实现抽象类中所定义的抽象方法和钩子方法,它们是一个顶级逻辑的组成步骤

🚀案例

例如我们在炒菜的时候,炒菜的步骤是固定的,分为倒油、热油、倒菜、倒调料品、翻炒等步骤。现通过模板方法模式来用代码模拟

🐤抽象类

在以下抽象类中,有具体的实现方法,如倒油、热油、翻炒,因为这些步骤是我们已知的,不管炒什么菜都需要经历这个步骤,但是炒的菜不一样我们倒的蔬菜就不一样,加的调料也不一样,因此把这一部分声明为抽象方法,在子类中再去实现。最后在cookProcess中按照顺序调用类中的方法。

public abstract class AbstractClass
{
    //第一步倒油,直接实现
    public void pourOil()
    {
        Console.WriteLine("倒油");
    }

    //第二步:热油是一样的,直接实现
    public void heatOil()
    {
        Console.WriteLine("热油");
    }

    //第三步:倒蔬菜
    public abstract void pourVegetable();

    //第四步:倒调味料是不一样
    public abstract void pourSauce();

    //第五步:翻炒是一样的,所以直接实现
    public void fry()
    {
        Console.WriteLine("炒啊炒啊炒到熟啊");
    }

    public void cookProcess()
    {
        //第一步:倒油
        this.pourOil();
        //第二步:热油
        this.heatOil();
        //第三步:倒蔬菜
        this.pourVegetable();
        //第四步:倒调味料
        this.pourSauce();
        //第五步:翻炒
        this.fry();
    }
}

🐤具体子类

炒辣包菜,实现抽象类中关于菜和配料的抽象方法。

public class ConcreteClass_BaoCai : AbstractClass
{
    public override void pourVegetable()
    {
        Console.WriteLine("下包菜");
    }

    public override void pourSauce()
    {
        Console.WriteLine("下辣椒");
    }
}

🐳同上

public class ConcreteClass_CaiXin : AbstractClass
{
    public override void pourVegetable()
    {
        Console.WriteLine("下菜心");
    }

    public override void pourSauce()
    {
        Console.WriteLine("下蒜蓉");
    }
}

🐤测试类

class MyClass
{
    public static void Main(string[] args)
    {
        var concreteClassBaoCai = new ConcreteClass_BaoCai();
        concreteClassBaoCai.cookProcess();
        Console.WriteLine("---------------------");
        var concreteClassCaiXin = new ConcreteClass_CaiXin();
        concreteClassCaiXin.cookProcess();
    }
}

运行结果!

🚀优缺点

优点:
  1. 提高代码复用性,将相同部分的代码放在抽象的父类中,而将不同的代码放入不同的子类中。
  2. 实现了反向控制,通过一个父类调用其子类的操作,通过对子类的具体实现扩展不同的行为,实现了反向控制 ,并符合开闭原则
缺点:
  1. 对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象。
  2. 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。
适用场景
  1. 算法的整体步骤很固定,但其中个别部分易变时,这时候可以使用模板方法模式,将容易变的部分抽象出来,供子类实现。
  2. 需要通过子类来决定父类算法中某个步骤是否执行,实现子类对父类的反向控制。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1058944.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

用 Pycharm 远程连接 Linux 服务器——超详细

用 Pycharm 远程连接 Linux 服务器——超详细 一、介绍二、要求三、服务器配置四、Pycharm远程连接Linux服务器 实战 一、介绍 本人是做NLP的,pycharm写的项目,数据集很大,在自己电脑上运行很慢,但是放到服务器上跑就很快。下面详…

FileZila 实现wind10与Linux系统文件互传

【FileZila】实现windows与Linux系统文件互传

哨兵(Sentinel-1、2)数据下载

哨兵(Sentinel-1、2)数据下载 一、登陆欧空局网站 二、检索 先下载2号为光学数据 分为S2A和S2B,产品种类有1C和2A,区别就是2A是做好大气校正的影像,当然数量也会少一些,云量检索条件中记得要按格式&#x…

Covert Communication隐蔽通信论文复现

文章目录 前言Covert Communications: A Comprehensive Surveyabstract简介隐蔽通信的概念和机制隐蔽通信的简要历史经典的Alice-Bob-Willie Model与其他安全技术的区别 一、Limits of Reliable Communication with Low Probability of Detection on AWGN Channels摘要introduc…

STM32复习笔记(三):串口

目录 Preface: (一)CUBEMX配置串口 (二)轮询方式 (三)中断 DMA Preface: 串口通信协议简单,因此被广泛应用;串口有UART(Universal Asynchron…

谷歌注册手机号码无法验证

1. 打开设置,在语言中点击添加语言搜索English并添加 2. 点击添加后把首选语言换成英语 3. 然后重启浏览器,这时候浏览器就是英文了,最后打开注册页面就能接收短信了

微服务技术栈-认识微服务和第一个微服务Demo

文章目录 前言一、认识微服务二、微服务技术栈三、Eureka注册中心四、微服务DEMO1、搭建eureka-server2、服务注册和服务发现 总结 前言 随着业务的不断复杂,对服务的要求也越来越高,服务架构也从单体架构逐渐演变为现在流行的微服务架构。 本章就从微服…

vuejs中缓存组件状态-keepAlive

前言 在 vuejs中,我们经常需要缓存一些组件的状态,比如用户登录后,切换到其他页面,再切换回来,需要保留之前的登录状态,而不是重新登录。 或者在切换不同组件的时候,需要保留之前的组件状态&…

[Linux]线程同步

[Linux]线程同步 文章目录 [Linux]线程同步线程同步线程饥饿问题概念 线程同步控制--条件变量pthread_cond_init函数pthread_cond_destroy函数pthread_cond_wait函数pthread_cond_signal函数pthread_cond_broadcast函数条件变量相关函数的使用示例生产者消费者模型基于Blocking…

基于SpringBoot的体育馆场地赛事预约管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序(小蔡coding)有保障的售后福利 代码参考源码获取 前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

【生命周期】

生命周期 1 引出生命周期2 分析生命周期3 总结生命周期 1 引出生命周期 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta …

互联网Java工程师面试题·MyBatis 篇·第二弹

目录 16、Xml 映射文件中&#xff0c;除了常见的 select|insert|updae|delete标签之外&#xff0c;还有哪些标签&#xff1f; 17、Mybatis 的 Xml 映射文件中&#xff0c;不同的 Xml 映射文件&#xff0c;id 是否可以重复&#xff1f; 18、为什么说 Mybatis 是半自动 ORM 映射…

证书显示未受信任,生成的证书过期

此时若是导入证书后&#xff0c;证书显示未受信任&#xff0c;则说明我们缺失最新的AppleWWDRCA证书 解决方案&#xff1a; 重新下载AppleWWDRCA并安装。即下载最新的AppleWWDRCA证书&#xff0c;双击安装到“登录”项的钥匙串下&#xff1b;然后再安装你的开发证书或者发布证书…

云原生微服务 第六章 Spring Cloud Netflix Eureka集成远程调用、负载均衡组件OpenFeign

系列文章目录 第一章 Java线程池技术应用 第二章 CountDownLatch和Semaphone的应用 第三章 Spring Cloud 简介 第四章 Spring Cloud Netflix 之 Eureka 第五章 Spring Cloud Netflix 之 Ribbon 第六章 Spring Cloud 之 OpenFeign 文章目录 系列文章目录前言1、OpenFeign的实现…

嵌入式Linux应用开发-驱动大全-第一章同步与互斥②

嵌入式Linux应用开发-驱动大全-第一章同步与互斥② 第一章 同步与互斥②1.3 原子操作的实现原理与使用1.3.1 原子变量的内核操作函数1.3.2 原子变量的内核实现1.3.2.1 ATOMIC_OP在 UP系统中的实现1.3.2.2 ATOMIC_OP在 SMP系统中的实现 1.3.3 原子变量使用案例1.3.4 原子位介绍1…

js正则的前瞻释义

/^(?a)aa$/可以匹配aa,但不能匹配aaa,因为前瞻不消耗字符串 检验密码强度的正则 /^(?.*[a-z])(?.*[A-Z])(?.*\d)(?.*[$,_.])[a-zA-Z\d$,_.]{6,12}$/var reg/^(?.*[a-z])(?.*[A-Z])(?.*\d)(?.*[$,_.])[a-zA-Z\d$,_.]{6,12}$/var res reg.test(abcdefg.A6)console.log(…

SpringBoot中使用Servlet和Filter

为什么要把Servlet和Filter写在一起,因为使用方式很相似 两种方式 第一种,使用Servlet和Filter 使用Servlet 继承HttpServlet 注册Servlet 使用Filter 1.自定义过滤器 2.注册过滤器 这里注意一点 使用/**无效 至少我这2.4.5版本是这样 过滤所有请求用/* 那么其实还有…

CodeCraft-21 and Codeforces Round 711 (Div. 2)A-F

1.Problem - A - Codeforces &#xff08;1&#xff09;题意 求一个大于等于n的整数x&#xff0c;满足gcd(x,sum(dig(x)) > 1&#xff0c;dig表示x的各个数位。 &#xff08;2&#xff09;思路 考虑最差是满足gcd(x,sum(dig(x)) 2,因此不会枚举很多&#xff0c;直接暴力枚…

【Diffusion】DDPM - (2)公式推导 之 前向扩散

1、加噪过程 1、将 图像 x 0 x_0 x0​ 像素值映射到 [-1, 1] 之间 x 255 2 − 1 , w h e r e    x 为图像中的像素值 \quad \frac{x}{255} \times 2-1, \quad where \; x 为图像中的像素值 255x​2−1,wherex为图像中的像素值 \quad 2、生成一张尺寸相同的噪声图片,像…

【Kafka专题】Kafka收发消息核心参数详解

目录 前置知识课程内容一、从基础的客户端说起&#xff08;Java代码集成使用&#xff09;1.1 消息发送者源码示例1.2 消息消费者源码示例1.3 客户端使用小总结 *二、从客户端属性来梳理客户端工作机制*2.1 消费者分组消费机制2.2 生产者拦截器机制2.3 消息序列化机制2.4 消息分…