C#设计模式-模板方法模式(Template Method)

概念

模板指一些能够套用的公共内容,例如网页模板是当网站中有许多页面版式色彩相同的状况下,将其定义为网页模板,并定义其中部分可编辑,部分不可编辑,那么在利用网页模板制做其余页面时就会很方便,不易出错。
在设计模式中,模板方法模式中模板和生活中模板概念很是相似,在一个抽象类中定义一个操做中的算法骨架(对应于模板),而将一些步骤延迟到子类中去实现(对应根据本身的状况向模板填充内容)。
在面向对象程序设计过程当中,程序员经常会遇到这种状况:设计一个系统时知道了算法所需的关键步骤,并且肯定了这些步骤的执行顺序,但某些步骤的具体实现还未知,或者说某些步骤的实现与具体的环境相关。此时就能够采用模板方法进行设计。程序员

例如公司的入职流程,进入公司,入职准备、入职报到、办理入职手续、进行入职培训,转正,入职结束进入岗位。这些步骤都很固定,可是不一样的公司,流程中每一个步骤稍有不一样。这些不一样的能够在具体实现上进行填充。算法

特色

优势:
它封装了不变部分,扩展可变部分。它把认为是不变部分的算法封装到父类中实现,而把可变部分算法由子类继承实现,便于子类继续扩展。
它在父类中提取了公共的部分代码,实现了代码复用。
部分方法是由子类实现的,所以子类能够经过扩展方式增长相应的功能,符合开闭原则。设计模式

缺点:
对每一个不一样的实现都须要定义一个子类,这会致使类的个数增长,系统更加庞大,设计也更加抽象。
父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这致使一种反向的控制结构,它提升了代码阅读的难度。
由于引入了一个抽象类,若是具体实现过多的话,须要用户或开发人员须要花更多的时间去理清类之间的关系。ide

模式结构

根据模板方法模式类图结构,有利于咱们理清该模式中类之间的关系,具体类图以下:网站

模板方法模式中涉及的角色:
抽象模板角色:定义了一个或多个抽象操做,以便让子类实现,这些抽象操做称为基本操做。它由一个模板方法和若干个基本方法构成。
  模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法。
  基本方法:是整个算法中的一个步骤,包含了抽象方法、具体方法。
具体模板角色:实现父类所定义的一个或多个抽象方法。this

应用场景

算法的总体步骤很固定,但其中个别部分易变时,这时候可使用模板方法模式,将容易变的部分抽象出来,供子类实现。
当多个子类存在公共的行为时,能够将其提取出来并集中到一个公共父类中以免代码重复。首先,要识别现有代码中的不一样之处,而且将不一样之处分离为新的操做。最后,用一个调用这些新的操做的模板方法来替换这些不一样的代码。lua

实现

以入职流程为例,进行具体的实现。spa

using System;

namespace 模板模式
{
    class EntryProcess
    {
        static void Main(string[] args)
        {
            SamsungEntryProcess samsung = new SamsungEntryProcess();
            HuaweiEntryProcess huawei = new HuaweiEntryProcess();

            samsung.JoiningCompany();
            huawei.JoiningCompany();

            Console.Read();
        }
    }

    // 抽象类,入职流程
    public abstract class TemplateEntryProcess
    {
        // 模板方法,不要把模版方法定义为 Virtual 或 abstract 方法,避免被子类重写,防止更改流程的执行顺序
        public void JoiningCompany()
        {
            this.entryCompany(); // 进入公司
            this.preparationForEntry(); // 入职前准备,整理衣帽等
            this.registrationForEmployment(); // 入职报到
            this.entryProcedures(); // 办理入职手续
            this.inductionTraining(); // 入职培训
            this.evaluationOfConversion(); // 转正评估
            this.entryOver(); // 入职结束,进入岗位
        }

        public abstract void entryCompany();

        public void preparationForEntry()
        {
            Console.WriteLine("作准备,整理衣帽等;");
        }

        public void registrationForEmployment()
        {
            Console.WriteLine("入职报到;");
        }
        public void entryProcedures()
        {
            Console.WriteLine("办理入职手续;");
        }
        public void inductionTraining()
        {
            Console.WriteLine("进行入职培训;");
        }
        public void evaluationOfConversion()
        {
            Console.WriteLine("完成入职前培训,进行转正评估;");
        }
        public void entryOver()
        {
            Console.WriteLine("入职流程完成,进入岗位。");
        }

    }

    // 具体子类,三星入职
    public class SamsungEntryProcess: TemplateEntryProcess
    {
        public override void entryCompany()
        {
            Console.WriteLine("进入三星公司");
        }

    }

    // 具体子类,华为入职
    public class HuaweiEntryProcess: TemplateEntryProcess
    {
        public override void entryCompany()
        {
            Console.WriteLine("进入华为公司");
        }
    }
}

执行后结果设计

进入三星公司
作准备,整理衣帽等;
入职报到;
办理入职手续;
进行入职培训;
完成入职前培训,进行转正评估;
入职流程完成,进入岗位。
进入华为公司
作准备,整理衣帽等;
入职报到;
办理入职手续;
进行入职培训;
完成入职前培训,进行转正评估;
入职流程完成,进入岗位。
相关文章
相关标签/搜索