设计模式——模板方法模式封装.net Core读取不同类型的文件

news/2024/5/19 22:43:36 标签: 设计模式, 模板方法模式, .netcore

1、模板方法模式

      模板方法模式:定义一个操作中的算法骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

      特点:通过把不变的行为搬移到超类,去除子类中重复的代码来体现它的优势。

模板方法模式提供了一个很好的代码复用平台。当不变的和可变的行为在子类实现中混合在一起的时候,不变的行为就会在子类中重复出现。我们通过模板方法模式把这些行为搬移到单一的地方,这样就帮助子类摆脱重复的不变的行为的纠缠。

2、Net Core 读取的类型文件

      读取不同类型文件的代码

 //读取JSON
 ConfigurationBuilder builder = new ConfigurationBuilder();
 builder.AddJsonFile("configuration.json");
 var config = builder.Build();
 var collections = config.AsEnumerable();

 //读取INI
 ConfigurationBuilder builder = new ConfigurationBuilder();
 builder.AddIniFile("configuration.ini");
 var config = builder.Build();
 var collections = config.AsEnumerable();

 //读取XML
 ConfigurationBuilder builder = new ConfigurationBuilder();
 builder.AddXmlFile("configuration.xml");
 var config = builder.Build();
 var collections = config.AsEnumerable();

如上代码:如果不使用模板方法模式,定义读取文件基类,子类中重写读取方法,如下代码

 //定义读取文件的基类
 public abstract class AFileRead
 {
     public abstract void Read(string path);
 }

 //定义读取JSON文件的子类
 public class FileReadJson:AFileRead
 {
     public override void Read(string path)
     {
         ConfigurationBuilder builder = new ConfigurationBuilder();
         builder.AddJsonFile(path);
         var config = builder.Build();
         var collections = config.AsEnumerable();
     }
 }

 //定义读取INI文件的子类
public class FileReadIni : AFileRead
{
    public override void Read(string path)
    {
        ConfigurationBuilder builder = new ConfigurationBuilder();
        builder.AddIniFile(path);
        var config = builder.Build();
        var collections = config.AsEnumerable();
    }
}
//定义读取XML文件的子类
 public class FileReadXml:AFileRead
 {
     public override void Read(string path)
     {
         ConfigurationBuilder builder = new ConfigurationBuilder();
         builder.AddXmlFile(path);
         var config = builder.Build();
         var collections = config.AsEnumerable();
     }
 }

上述代码中,只有一行读取不同类型文件代码不同,其余代码都相同。这只是单独的一个读取文件的功能,代码量很小,如果是一个特别大的功能,代码过多,那么如果要更改的话,工作量也是很大的。

为了减少重复的代码,如何去解决这个问题?

       这个时候,模板方法模式,就起作用了。模板方法模式将子类中不变的行为定义到基类中,子类中只留下可变的行为,这样子类中就摆脱了重复代码的纠缠,代码如下:

//定义读取文件的接口
public interface IFileRead
{
    IEnumerable<KeyValuePair<string,string>> ReadFile();
}

//定义读取文件,封装重复代码,将可变的行为延迟到子类中实现
public abstract class AFileRead : IFileRead
{
    public IEnumerable<KeyValuePair<string, string>> ReadFile()
    {
        ConfigurationBuilder builder = new ConfigurationBuilder();
        AddFile(builder);  
        var config = builder.Build();
        var collections = config.AsEnumerable();
        return collections;
    }
    //这个函数需要延迟到子类中去实现
    protected abstract IConfigurationBuilder AddFile(ConfigurationBuilder builder);
}
//读取JSON文件
public class ReadJsonFile : AFileRead
{
    protected override IConfigurationBuilder AddFile(ConfigurationBuilder builder)
    {
        return builder.AddJsonFile("configuration.json");
    }
}
//读取XML文件
public class ReadXmlFile : AFileRead
{
    protected override IConfigurationBuilder AddFile(ConfigurationBuilder builder)
    {
        return builder.AddXmlFile("configuration.xml");
    }
}
//读取Ini文件
public class ReadIniFile : AFileRead
{
    protected override IConfigurationBuilder AddFile(ConfigurationBuilder builder)
    {
        return builder.AddIniFile("configuration.ini");
    }
}

总结: 模板方法模式,帮助我们封装了不变的行为,涉及到实现某些特定步骤时,就延迟到了子类中去实现,在更改某个读取文件的函数时,不会影响到其他读取文件的功能。


http://www.niftyadmin.cn/n/5441418.html

相关文章

arm核的DMPIS是如何计算的

直接看这篇&#xff1a;https://zhuanlan.zhihu.com/p/660155292 写的很好&#xff1a; "SA8155P的CPU算力计算如下&#xff08;按照A75性能提升50%来计算&#xff0c;即 5.2 * 1.5 7.8 DMIPS/MHz &#xff09; SA8155P算力 2.419GHz * 1核 * 7.8 DMIPS/MHz 2.131GH…

【LeetCode: 224. 基本计算器 + 模拟 + 栈】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

企业如何选择一个开源「好」项目?

开源 三句半 oss-roast 需求明确是关键 风险考量要周全 开源虽好不白捡 别忘合规&#xff01; 显然&#xff0c;开源已成为一股不可阻挡的洪流&#xff0c;企业拥抱开源&#xff0c;积极参与开源项目不仅是响应技术潮流的必然选择&#xff0c;更是实现自身技术创新、市场拓展等…

【C++】为什么vector的地址与首元素地址不同?

文章目录 一、问题发现&#xff1a;二、结果分析三、问题解析 一、问题发现&#xff1a; &vector和&vector[0]得到的两个地址居然不相同&#xff0c;对数组array取变量名地址和取首元素地址的结果是相同的。这是为啥呢&#xff1f; 使用下面代码进行验证&#xff1a;…

【Kotlin】扩展属性、扩展函数

1 类的扩展 Kotlin 提供了扩展类或接口的操作&#xff0c;而无需通过类继承或使用装饰器等设计模式&#xff0c;来为某个类添加一些额外的属性或函数&#xff0c;我们只需要通过一个被称为扩展的特殊声明来完成。通过这种机制&#xff0c;我们可以将那些第三方类不具备的功能强…

AIOCR:AI文字识别web集成系统@Kylin+RISCV

基于kotti_ai的AI文字识别web集成系统 AIOCR项目目标&#xff1a; 在KylinRISCV搭建一个kotti_ai构架的网站&#xff0c;提供AI OCR文字识别web服务。 二期目标&#xff1a;在AIOCR的基础上提供chatgpt和文心一言等大模型调用&#xff0c;建立综合大模型应用平台。 功能&am…

Kafka总结问题

Kafka KafkaKafka Kafka的核心概念/ 结构 topoic Topic 被称为主题,在 kafka 中,使用一个类别属性来划分消息的所属类,划分消息的这个类称为 topic。topic 相当于消息的分配标签,是一个逻辑概念。主题好比是数据库的表,或者文件系统中的文件夹。partition partition 译为分…

Unity Toggle与Toggle Group的妙用

Toggle与Toggle Group结合使用&#xff0c;妙处多多。 因为在同一Toggle Group内只有一个Toggle可以被选中&#xff0c;那么对于我们要创建单选按钮组、游戏的一些开关、暗夜模式、筛选不同显示内容等功能都非常好用。 比如我要实现通过点击不同按钮,从而筛选显示不同内容&am…