首页 > 编程语言 >C#设计模式14——模板方法的写法

C#设计模式14——模板方法的写法

时间:2023-05-09 22:24:51浏览次数:44  
标签:14 C# 子类 算法 步骤 抽象类 设计模式 方法 public

模板方法(Template Method)是一种设计模式,它定义了一个操作中的算法的骨架,将某些步骤推迟到子类中实现,从而使得子类可以在不改变算法骨架的情况下重新定义算法的某些步骤。

作用:

使用模板方法可以使得代码的重复度降低,同时也能够避免由于算法中某个特定步骤的改变导致整体算法需要改变的情况。此外,模板方法也使得维护和扩展代码变得更加容易。

怎么做:

在C#中,可以通过抽象类和虚方法来实现模板方法。具体的做法是,定义一个抽象类,声明大致的算法流程,并将其中某些步骤声明为虚方法,待子类继承该抽象类后,根据需要实现其虚方法。这样,就可以通过调用抽象类中的算法流程,由子类来具体实现算法中的某些步骤,从而得出结果。

何时用:

模板方法常用于以下场景:

1.在多个类中有相同的方法,但具体的实现细节有所不同。

2.需要在代码中使用一种算法,但是该算法中某些步骤需要根据具体情况进行不同的实现。

3.需要保证所有使用该算法的地方都能得到相同的结果。

4.需要把具体的实现过程从算法中分离开来,使得算法更容易扩展和维护。

5.需要让子类只能实现算法中的某一部分,而不能改变整个算法的结构。

如何实现:

在C#中,使用模板方法的关键是要定义一个抽象类,包含所有的算法流程,但某些步骤需要由子类来具体实现。因此,在抽象类中,通常会定义一些虚方法,用于在子类中具体实现算法。抽象类的代码示例:

//抽象类
public abstract class AbstractClass
{
    //模板方法,定义算法骨架
    public void TemplateMethod()
    {
        //步骤1
        Step1();

        //步骤2
        Step2();

        //步骤3
        Step3();
    }

    //步骤1(抽象方法,由子类具体实现)
    public abstract void Step1();

    //步骤2(虚方法,子类可以覆盖,默认实现为空)
    public virtual void Step2()
    {
        //默认实现为空
    }

    //步骤3(抽象方法,由子类具体实现)
    public abstract void Step3();
}

在抽象类中,定义了一个模板方法TemplateMethod(),其中具体的算法流程已经定义好了,但某些步骤则需要由子类来具体实现,因此,在抽象类中,对于某些需要具体实现的步骤,我们使用抽象方法进行声明,在子类中需要对这些抽象方法进行具体实现;而对于某些步骤,它们的实现可以在基类中进行默认实现,因此,我们可以使用虚方法进行声明,在子类中也可以选择覆盖这些虚方法。

下面是一个使用模板方法的示例:

//具体类1
public class ConcreteClassA : AbstractClass
{
    public override void Step1()
    {
        Console.WriteLine("ConcreteClassA:Step1");
    }

    public override void Step3()
    {
        Console.WriteLine("ConcreteClassA:Step3");
    }
}

//具体类2
public class ConcreteClassB : AbstractClass
{
    public override void Step1()
    {
        Console.WriteLine("ConcreteClassB:Step1");
    }

    public override void Step2()
    {
        Console.WriteLine("ConcreteClassB:Step2");
    }

    public override void Step3()
    {
        Console.WriteLine("ConcreteClassB:Step3");
    }
}

//客户端调用
class Client
{
    static void Main(string[] args)
    {
        AbstractClass ac1 = new ConcreteClassA();
        ac1.TemplateMethod();

        AbstractClass ac2 = new ConcreteClassB();
        ac2.TemplateMethod();
    }
}

在这个示例中,我们定义了两个具体类——ConcreteClassA和ConcreteClassB,它们都继承了抽象类AbstractClass,并根据需要实现了其中的虚方法。

在主函数中,我们实例化了这两个具体类,并分别调用它们的TemplateMethod()方法,从而得到了两个具体类的实例化对象。这些对象都实现了同样的模板方法(算法流程),但由于其中某些步骤使用了不同的实现方法,输出结果也不同: 

```
ConcreteClassA:Step1
ConcreteClassA:Step2
ConcreteClassA:Step3

ConcreteClassB:Step1
ConcreteClassB:Step2
ConcreteClassB:Step3
``` 

 

标签:14,C#,子类,算法,步骤,抽象类,设计模式,方法,public
From: https://www.cnblogs.com/for-easy-fast/p/17386484.html

相关文章

  • 1009 说反话(C++)
    一、问题描述:给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。输入格式:测试输入包含一个测试用例,在一行内给出总长度不超过80的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用1个空格分开,输入保证句子末尾没有......
  • Git的命令git diff和git diff --cached的作用
    1.首先看一下diff 举一个例子,比较文件t.txt和tc.txt这两个文件的差异性diff也是GNU/LINUX生态系统中的一个重要的工具,众所周知的是,linux的很多很多工具都是可以协作使用的。比如Git中就借助了diff这个文件差异性工具 2.关于gitdiff:比较本地文件和暂存区(stagingarea,ind......
  • [HUBUCTF 2022 新生赛]simple_RE
    查壳:64位,进IDA:看正确输出:有要比较的两个字符a5mc58bphliax7j和Buf1,可以知道目的字符串是a5mc58bphliax7j,跟进看看:再看看Buf1,可以看见它是根据我们输入的字符进行sub_401570方法后得到的,那么我们跟进:熟悉的配方,base64加密格式,看看是否为标码:很明显,不是,而且不是替换,而是......
  • C# HttpListener 和 HttpServer区别
    HttpListener和HttpServer都是C#中用于创建HTTP服务器的类库,它们的作用都是监听HTTP请求,并向客户端发送HTTP响应。它们的主要区别在于实现方式和使用场景。HttpListener是.NETFramework中的一个类,它提供了一种基于事件的异步API,可以用于创建一个轻量级的HTTP服......
  • 用C#将多个jpg合成一个pdf
    nuget安装iTextSharp:staticvoidMergePDF(stringpicPath,stringpdfPath){string[]picFileNames=Directory.GetFiles(picPath,"*");List<string>fileNames=picFileNames.ToList();fileNames.Sort((l,......
  • c++打卡练习(23)
    亲密数如果整数A的全部因子(包括1,不包括A本身)之和等于B;且整数B的全部因子(包括1,不包括B本身)之和等于A,则将整数A和B称为亲密数。求3000以内的全部亲密数。流程图:伪代码:源代码:#include<iostream>usingnamespacestd;intmain(){ inta,i,b,n; printf("Therearefollowing......
  • 入门8-Pytest部分测试用例的前后置(fixture)(2-conftest.py结合)
    conftest.py文件专门用来存放fixture的文件,名称固定不能修改。conftest.py中的所有方法在调用时都不需要导包一个用例可以同时调用多个conftest.py中的多个方法一般conftest.py中的方法autouse=True, 自动执行。conftest.py放在最外层,使用scope="session"时,整个项目开头执......
  • linux之docker安装RocketMQ
    一、创建namesrv容器dockerpullrocketmqinc/rocketmqmkdir-p/docker/rocketmq/data/namesrv/logs/docker/rocketmq/data/namesrv/storedockerrun-d\--restart=always\--namermqnamesrv\-p9876:9876\-v/docker/rocketmq/data/namesrv/logs:/root/lo......
  • Spring-MVC-随笔
    Spring-MVC一、SpringMVC简介1、什么是MVCMVC是一种软件架构的思想,将软件按照模型、视图、控制器来划分M:Model,模型层,指工程中的JavaBean,作用是处理数据JavaBean分为两类:一类称为实体类Bean:专门存储业务数据的,如Student、User等一类称为业务处理Bean:指Service或Dao......
  • 【Azure 存储服务】使用 AppendBlobClient 对象实现对Blob进行追加内容操作
    问题描述在AzureBlob的官方示例中,都是对文件进行上传到Blob操作,没有实现对已创建的Blob进行追加的操作。如果想要实现对一个文件的多次追加操作,每一次写入的时候,只传入新的内容? 问题解答AzureStorageBlob有三种类型:BlockBlob,AppendBlob和PageBlob。其中,只有Appen......