C# 设计模式之模板方法模式

总目录


前言

在日常的工作中,有时候我们做PPT,做合同,做简历,如果我们自己从头去写这些文档,不免有些太过耗时耗力;大多时候都是去找相关的PPT模板,合同模板,简历模板,拿过来直接用。为什么可以使用模板,因此这些资料大部分的信息和信息框架都是一致的,我们只需要将自己差异化的内容填写进去就可以,模板的作用就是将公有的格式,框架,信息提取出来都做好,使用模板的人只需填写个人差异化的信息即可。模板方法设计模式就是按照这个思想来设计代码的,在软件构建过程中,对于某一项任务,如果它常常有稳定的整体操作结构,但各个子步骤内却有很多改变的需求,这个时候就可以应用模板方法模式。


1 基础介绍

  1. 定义:定义一个操作中的算法骨架,将某些步骤延迟到子类中实现。
  2. 定义解释:在一个抽象类中定义一个操作中的算法骨架(对应于生活中的大家下载的模板),而将一些步骤延迟到子类中去实现(对应于我们根据自己的情况向模板填充内容)。模板方法使得子类可以不改变一个算法的结构前提下,重新定义算法的某些特定步骤,模板方法模式把不变行为搬到基类中,从而去除了子类中的重复代码。
  3. 模板方法模式中的角色:
    • 抽象类角色(AbstractClass):定义一个模板方法(TemplateMethod),在该方法中包含着一个算法的骨架,具体的算法步骤是PrimitiveOperation1方法和PrimitiveOperation2方法,该抽象类的子类将重定义PrimitiveOperation1和PrimitiveOperation2操作。
    • 具体类角色(ConcreteClass):实现PrimitiveOperation1方法和PrimitiveOperation2方法以完成算法中与特定子类(Client)相关的内容。
  4. 模板方法模式在抽象类中定义了算法的实现步骤,将这些步骤的实现延迟到具体子类中去实现,从而使所有子类复用了父类的代码,所以模板方法模式是基于继承的一种实现代码复用的技术。

2 使用场景

适用于 某个功能需要多个步骤实现,整体的实现步骤是不变的,只是具体的某些子步骤会存在差异的情况,这样就可以将实现步骤提取到基类,具体的实现交给实现类去完成。

3 实现方式

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

    public abstract class AbstractClass
    {
        public void TemplateMethod()
        {
            // 模板方法,定义算法骨架  
            //步骤1
            PrimitiveOperation1();
            //步骤2
            PrimitiveOperation2();
            //步骤3
            PrimitiveOperation3();
            // ...  
        }

        // 步骤1(原始操作1):抽象方法,由子类具体实现
        public abstract void PrimitiveOperation1(); 

        //步骤2(原始操作2):抽象方法,由子类具体实现
        public abstract void PrimitiveOperation2();

        //步骤3(原始操作2):抽象方法,由子类具体实现
        public virtual void PrimitiveOperation3()
        {
            //在这里这里写上基类会有的基本操作
            Console.WriteLine("AbstractClass:base Operation3");
            //也可以什么都不写,默认实现为空,交由子类重写
        }

    }

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

然后,创建两个继承自AbstractClass的具体类,实现这些抽象方法:

    public class ConcreteClassA : AbstractClass
    {
        public override void PrimitiveOperation1()
        {
            Console.WriteLine("ConcreteClassA: PrimitiveOperation1");
        }

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

    public class ConcreteClassB : AbstractClass
    {
        public override void PrimitiveOperation1()
        {
            Console.WriteLine("ConcreteClassB: PrimitiveOperation1");
        }

        public override void PrimitiveOperation2()
        {
            Console.WriteLine("ConcreteClassB: PrimitiveOperation2");
        }
		
		// 这里基于virtual方法重写,并加上自有的代码
        public override void PrimitiveOperation3()
        {
            base.PrimitiveOperation3();
            Console.WriteLine("ConcreteClassB: PrimitiveOperation3");
        }
    }

客户端调用:

        static void Main(string[] args)
        {
            AbstractClass abstractClass = new ConcreteClassA();
            
            // 调用TemplateMethod方法,
            //该方法会依次调用ConcreteClassA实现类中的各个实现方法
            abstractClass.TemplateMethod();
 
            abstractClass = new ConcreteClassB(); 
            
            // 再次调用TemplateMethod方法,这次会使用ConcreteClassB的实现。
            abstractClass.TemplateMethod();

            Console.ReadKey();

        }

4 优缺点分析

  • 优点

    • 使用模板方法可以使得代码的重复度降低,代码得到复用
    • 能够灵活应对子步骤的变化,符合开放-封闭原则
  • 缺点

    • 由于引入了一个抽象类,使程序代码变得复杂化

结语

希望以上内容可以帮助到大家,如文中有不对之处,还请批评指正。


参考资料:
C#设计模式14——模板方法的写法
C#设计模式之十三模板方法模式(Template Method Pattern)【行为型】
C#设计模式(14)——模板方法模式(Template Method)
使用 C# 实现23种常见的设计模式

  • 20
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值