23种设计模式之《模板方法模式(Template Method)》在c#中的应用及理解
程序设计中的主要设计模式通常分为三大类,共23种:
1. 创建型模式(Creational Patterns)
-
单例模式(Singleton):确保一个类只有一个实例,并提供全局访问点。
-
工厂方法模式(Factory Method):定义创建对象的接口,由子类决定实例化哪个类。
-
抽象工厂模式(Abstract Factory):提供一个创建一系列相关或依赖对象的接口,而无需指定具体类。
-
建造者模式(Builder):将一个复杂对象的构建与其表示分离,使同样的构建过程可以创建不同的表示。
-
原型模式(Prototype):通过复制现有对象来创建新对象。
2. 结构型模式(Structural Patterns)
-
适配器模式(Adapter):将一个类的接口转换成客户希望的另一个接口。
-
桥接模式(Bridge):将抽象部分与实现部分分离,使它们可以独立变化。
-
组合模式(Composite):将对象组合成树形结构以表示“部分-整体”的层次结构。
-
装饰器模式(Decorator):动态地给对象添加职责,相比生成子类更为灵活。
-
外观模式(Facade):为子系统中的一组接口提供一个统一的接口。
-
享元模式(Flyweight):通过共享技术有效地支持大量细粒度对象。
-
代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。
3. 行为型模式(Behavioral Patterns)
-
责任链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者与接收者耦合。
-
命令模式(Command):将请求封装为对象,使你可以用不同的请求对客户进行参数化。
-
解释器模式(Interpreter):给定一个语言,定义其文法的一种表示,并定义一个解释器。
-
迭代器模式(Iterator):提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部表示。
-
中介者模式(Mediator):定义一个中介对象来封装一系列对象之间的交互。
-
备忘录模式(Memento):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
-
观察者模式(Observer):定义对象间的一对多依赖关系,当一个对象改变状态时,所有依赖者都会收到通知并自动更新。
-
状态模式(State):允许对象在其内部状态改变时改变其行为。
-
策略模式(Strategy):定义一系列算法,将它们封装起来,并使它们可以互相替换。
-
模板方法模式(Template Method):定义一个操作中的算法骨架,将一些步骤延迟到子类中。
-
访问者模式(Visitor):表示一个作用于某对象结构中的各元素的操作,使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。
4.模板方法模式(Template Method Pattern)解释
模板方法模式是一种行为设计模式,它定义了一个算法的框架,并允许子类在不改变算法结构的情况下重新定义算法的某些步骤。模板方法模式的核心思想是将算法的通用部分放在父类中,而将可变的部分留给子类去实现。
模板方法模式的主要组成部分包括:
- 抽象类(Abstract Class):定义了一个模板方法,该方法包含了算法的骨架。模板方法通常会调用一些抽象方法或钩子方法,这些方法由子类实现。
- 具体类(Concrete Class):实现了抽象类中的抽象方法或钩子方法,从而具体化了算法的某些步骤。
模板方法模式的关键在于:父类控制算法的流程,子类实现具体的步骤。这种方式可以避免代码重复,并且使得算法的扩展更加灵活。
5.C# 实现模板方法模式的演示代码
csharp
using System;// 抽象类:定义模板方法和算法的骨架
public abstract class AbstractClass
{// 模板方法:定义了算法的流程public void TemplateMethod(){Step1();Step2();Step3();HookMethod(); // 钩子方法,子类可以选择是否重写}// 具体步骤1:抽象方法,子类必须实现protected abstract void Step1();// 具体步骤2:抽象方法,子类必须实现protected abstract void Step2();// 具体步骤3:默认实现,子类可以选择是否重写protected virtual void Step3(){Console.WriteLine("AbstractClass: Default implementation of Step3");}// 钩子方法:默认实现,子类可以选择是否重写protected virtual void HookMethod(){Console.WriteLine("AbstractClass: Default implementation of HookMethod");}
}// 具体类A:实现抽象类中的抽象方法
public class ConcreteClassA : AbstractClass
{protected override void Step1(){Console.WriteLine("ConcreteClassA: Step1");}protected override void Step2(){Console.WriteLine("ConcreteClassA: Step2");}// 重写Step3,提供自定义实现protected override void Step3(){Console.WriteLine("ConcreteClassA: Custom implementation of Step3");}// 重写钩子方法,提供自定义实现protected override void HookMethod(){Console.WriteLine("ConcreteClassA: Custom implementation of HookMethod");}
}// 具体类B:实现抽象类中的抽象方法
public class ConcreteClassB : AbstractClass
{protected override void Step1(){Console.WriteLine("ConcreteClassB: Step1");}protected override void Step2(){Console.WriteLine("ConcreteClassB: Step2");}// 不重写Step3,使用默认实现// 不重写HookMethod,使用默认实现
}// 客户端代码
class Program
{static void Main(string[] args){Console.WriteLine("Client: Testing ConcreteClassA");AbstractClass classA = new ConcreteClassA();classA.TemplateMethod();Console.WriteLine("\nClient: Testing ConcreteClassB");AbstractClass classB = new ConcreteClassB();classB.TemplateMethod();}
}
6.代码说明
-
抽象类(AbstractClass):
- 定义了模板方法
TemplateMethod,它包含了算法的骨架。 - 包含两个抽象方法
Step1和Step2,子类必须实现。 - 包含一个默认实现的方法
Step3,子类可以选择是否重写。 - 包含一个钩子方法
HookMethod,子类可以选择是否重写。
- 定义了模板方法
-
具体类A(ConcreteClassA):
- 实现了抽象方法
Step1和Step2。 - 重写了
Step3和HookMethod,提供了自定义实现。
- 实现了抽象方法
-
具体类B(ConcreteClassB):
- 实现了抽象方法
Step1和Step2。 - 没有重写
Step3和HookMethod,使用默认实现。
- 实现了抽象方法
-
客户端代码:
- 创建了
ConcreteClassA和ConcreteClassB的实例,并调用它们的TemplateMethod,展示了不同子类的行为。
- 创建了
7.运行结果
Client: Testing ConcreteClassA
ConcreteClassA: Step1
ConcreteClassA: Step2
ConcreteClassA: Custom implementation of Step3
ConcreteClassA: Custom implementation of HookMethodClient: Testing ConcreteClassB
ConcreteClassB: Step1
ConcreteClassB: Step2
AbstractClass: Default implementation of Step3
AbstractClass: Default implementation of HookMethod
8.总结
模板方法模式通过将算法的框架放在父类中,而将具体步骤的实现交给子类,实现了代码的复用和扩展性。它的主要优点包括:
- 代码复用:算法的通用部分在父类中实现,避免了代码重复。
- 扩展性:子类可以灵活地实现或重写某些步骤,而不需要修改算法的整体结构。
- 控制流程:父类控制算法的流程,子类只需关注具体的实现细节。
模板方法模式常用于框架设计、算法实现等场景,例如在开发库或框架时,可以为用户提供一个可扩展的算法模板。
相关文章:
23种设计模式之《模板方法模式(Template Method)》在c#中的应用及理解
程序设计中的主要设计模式通常分为三大类,共23种: 1. 创建型模式(Creational Patterns) 单例模式(Singleton):确保一个类只有一个实例,并提供全局访问点。 工厂方法模式࿰…...
DEV-C++ 为什么不能调试?(正确解决方案)
为了备战pat考试,专门下载了DEV C,然后懵圈的发现,怎么无法调试(╯□)╯︵ ┻━┻ 然后整了半天,终于在网上找到相应的解决方案!!!-> Dev C 5.11 调试初始设置 <- 一共四步…...
【C++设计模式】第五篇:原型模式(Prototype)
注意:复现代码时,确保 VS2022 使用 C17/20 标准以支持现代特性。 克隆对象的效率革命 1. 模式定义与用途 核心思想 原型模式:通过复制现有对象(原型)来创建新对象,而非通过new构造。关键用…...
深入 Vue.js 组件开发:从基础到实践
深入 Vue.js 组件开发:从基础到实践 Vue.js 作为一款卓越的前端框架,其组件化开发模式为构建高效、可维护的用户界面提供了强大支持。在这篇博客中,我们将深入探讨 Vue.js 组件开发的各个方面,从基础概念到高级技巧,助…...
maven导入spring框架
在eclipse导入maven项目, 在pom.xml文件中加入以下内容 junit junit 3.8.1 test org.springframework spring-core ${org.springframework.version} org.springframework spring-beans ${org.springframework.version} org.springframework spring-context ${org.s…...
数据守护者:备份文件的重要性与自动化实践策略
在数字化浪潮席卷全球的今天,数据已成为企业运营和个人生活中不可或缺的核心资源。无论是企业的财务报表、客户资料,还是个人的家庭照片、工作文档,这些数据都承载着巨大的价值。然而,数据丢失的风险无处不在,硬件故障…...
MyBatis @Param 注解详解:指定的参数找不到?
MyBatis Param 注解详解 1. Param 注解的作用 Param 注解用于显式指定方法参数的名称,让 MyBatis 在 SQL 映射文件(XML)或注解中通过该名称访问参数。 核心场景: 方法有多个参数时,避免参数名丢失或混淆。参数为简单…...
【项目日记(八)】内存回收与联调
前言 我们前面实现了三层缓存申请的过程,并完成了三层缓存申请过程的联调!本期我们来介绍三层的缓存的回收机制以及三层整体联调释放的过程。 目录 前言 一、thread cache 回收内存 二、central cache 回收内存 • 如何确定一个对象对应的span • …...
性能测试监控工具jmeter+grafana
1、什么是性能测试监控体系? 为什么要有监控体系? 原因: 1、项目-日益复杂(内部除了代码外,还有中间件,数据库) 2、一个系统,背后可能有多个软/硬件组合支撑,影响性能的因…...
016.3月夏令营:数理类
016.3月夏令营:数理类: 中国人民大学统计学院: http://www.eeban.com/forum.php?modviewthread&tid386109 北京大学化学学院第一轮: http://www.eeban.com/forum.php?m ... 6026&extrapage%3D1 香港大学化学系夏令营&a…...
CS144 Lab Checkpoint 0: networking warm up
Set up GNU/Linux on your computer 我用的是Ubuntu,按照指导书上写的输入如下命令安装所需的软件包: sudo apt update && sudo apt install git cmake gdb build-essential clang \ clang-tidy clang-format gcc-doc pkg-config glibc-doc tc…...
靶场之路-VulnHub-DC-6 nmap提权、kali爆破、shell反连
靶场之路-VulnHub-DC-6 一、信息收集 1、扫描靶机ip 2、指纹扫描 这里扫的我有点懵,这里只有两个端口,感觉是要扫扫目录了 nmap -sS -sV 192.168.122.128 PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.4p1 Debian 10deb9u6 (protoc…...
给没有登录认证的web应用添加登录认证(openresty lua实现)
这阵子不是deepseek火么?我也折腾了下本地部署,ollama、vllm、llama.cpp都弄了下,webui也用了几个,发现nextjs-ollama-llm-ui小巧方便,挺适合个人使用的。如果放在网上供多人使用的话,得接入登录认证才好&a…...
3月5日作业
代码作业: #!/bin/bash# 清空目录函数 safe_clear_dir() {local dir"$1"local name"$2"if [ -d "$dir" ]; thenwhile true; doread -p "检测到 $name 目录已存在,请选择操作: 1) 清空目录内容 2) 保留目…...
【MySQL】增删改查
目录 一、新增(Create) 单行数据 全列插入 多行数据 指定列插入 插入时间 二、查询(Retrieve) 全列查询 指定列查询 查询字段为表达式 别名 去重:DISTINCT 排序:ORDER BY 条件查询࿱…...
【三维生成】StarGen:基于视频扩散模型的可扩展的时空自回归场景生成
标题:《StarGen: A Spatiotemporal Autoregression Framework with Video Diffusion Model for Scalable and Controllable Scene Generation》 项目:https://zju3dv.github.io/StarGen 来源:商汤科技、浙大CAD、Tetras.AI 文章目录 摘要一、…...
线反转法实现矩形键盘按键识别
由于行、列线为多键共用,各按键彼此将相互发 生影响,必须将行、列线信号配合起来并作适当的处 理,才能确定闭合键的位置。 线反转法 第1步:列线输出为全低电平,则行线中电平由高变低 的所在行为按键所在行。 第2步&…...
在 Element Plus 的 <el-select> 组件中,如果需要将 <el-option> 的默认值设置为 null。 用于枚举传值
文章目录 引言轻松实现 `<el-option>` 的默认值为 `null`I 实现方式监听清空事件 【推荐】使用 v-model 绑定 null添加一个值为 null 的选项处理 null 值的显示引言 背景:接口签名规则要求空串参与,空对象不参与签名计算 // 空字符串“” 参与签名组串,null不参与签…...
大白话面试中应对自我介绍
在面试中,自我介绍是开场的关键环节,它就像你递给面试官的一张“个人名片”,要让面试官快速了解你并对你产生兴趣。下面详细讲讲应对自我介绍的要点及回答范例。 一、自我介绍的时间把控 一般面试中的自我介绍控制在1 - 3分钟比较合适。时间…...
Pytorch构建LeNet进行MNIST识别 #自用
LeNet是一种经典的卷积神经网络(CNN)结构,由Yann LeCun等人在1998年提出,主要用于手写数字识别(如MNIST数据集)。作为最早的实用化卷积神经网络,LeNet为现代深度学习模型奠定了基础,…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...
