且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

【愚公系列】2021年12月 二十三种设计模式(二十二)-模板方法模式(Template Method Pattern)

更新时间:2022-05-12 16:54:45

文章目录

前言

一、模板方法模式(Template Method Pattern)

二、使用步骤

角色

示例

总结

优点

缺点

使用场景

前言

设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因。


提示:以下是本篇文章正文内容,下面案例可供参考


一、模板方法模式(Template Method Pattern)

模板方法模式属于行为型模式,定义一个模板结构,将具体内容延迟到子类去实现。


在不改变模板结构的前提下在子类中重新定义模板中的内容。


二、使用步骤

角色

1、抽象类(Abstract Class)


实现了模板方法,定义了算法的框架;


2、具体类(Concrete Class)


实现抽象类中的抽象方法,以完成完整的算法。


示例

【愚公系列】2021年12月 二十三种设计模式(二十二)-模板方法模式(Template Method Pattern)

命名空间TemplateMethod中包含DataSource数据源抽象类,其中有一些实例方法、抽象方法和钩子方法(IsNotJson),ShowChart方法使用数据源显示一个图表。本示例使用这个案例来向大家讲解模板方法模式的实现要领。

public abstract class DataSource {

    protected abstract void FetchSource();

    protected virtual bool IsNotJson() {
        return true;
    }

    protected abstract void Convert2Json();

    protected abstract void ShowData();

    public void ShowChart() {
        FetchSource();
        if (IsNotJson()) {
            Convert2Json();
        }
        ShowData();
        Console.WriteLine("----------------------------------");
    }

}

数据源抽象基类DataSouce,包含取数据FetchSource方法,是否是Json数据IsNotJson方法,转化成Json格式Convert2Json方法,最后是显示数据图表ShowChart方法。

public class TextData : DataSource {
 
    protected override void FetchSource() {
        Console.WriteLine($"Fetch data from {this.ToString()}!");
    }
 
    protected override void Convert2Json() {
        Console.WriteLine($"Convert {this.ToString()} to Json!");
    }
 
    protected override void ShowData() {
        Console.WriteLine($"Show data in chart control!");
    }
 
}

文本数据源TextData类。

public class BinaryData : DataSource {
 
    protected override void FetchSource() {
        Console.WriteLine($"Fetch data from {this.ToString()}!");
    }
 
    protected override void Convert2Json() {
        Console.WriteLine($"Convert {this.ToString()} to Json!");
    }
 
    protected override void ShowData() {
        Console.WriteLine($"Show data in chart control!");
    }
 
}

二进制数据源BinaryData类。

public class JsonData : DataSource {
 
    protected override void FetchSource() {
        Console.WriteLine($"Fetch data from {this.ToString()}!");
    }
 
    protected override bool IsNotJson() {
        return false;
    }
 
    protected override void Convert2Json() {
        Console.WriteLine("This line can not be reached!");
        Console.WriteLine("There's no need to convert data!");
    }
 
    protected override void ShowData() {
        Console.WriteLine($"Show data in chart control!");
    }
 
}

Json数据源JsonData类。

public class CloudData : DataSource {
 
    protected override void FetchSource() {
        Console.WriteLine($"Fetch data from {this.ToString()}!");
    }
 
    protected override void Convert2Json() {
        Console.WriteLine($"Convert {this.ToString()} to Json!");
    }
 
    protected override void ShowData() {
        Console.WriteLine($"Show data in chart control!");
    }
 
}

云数据源CloudData类。

public class Program {

    private static DataSource _dataSource = null;

    public static void Main(string[] args) {
        _dataSource = new TextData();
        _dataSource.ShowChart();

        _dataSource = new BinaryData();
        _dataSource.ShowChart();

        _dataSource = new JsonData();
        _dataSource.ShowChart();

        _dataSource = new CloudData();
        _dataSource.ShowChart();

        Console.ReadKey();
    }

}

以上是调用方的代码,以下是这个案例的输出结果:

Fetch data from TemplateMethod.TextData!
Convert TemplateMethod.TextData to Json!
Show data in chart control!
----------------------------------
Fetch data from TemplateMethod.BinaryData!
Convert TemplateMethod.BinaryData to Json!
Show data in chart control!
----------------------------------
Fetch data from TemplateMethod.JsonData!
Show data in chart control!
----------------------------------
Fetch data from TemplateMethod.CloudData!
Convert TemplateMethod.CloudData to Json!
Show data in chart control!
----------------------------------

总结

优点

1、提高代码复用性,可以将相同部分的代码放在抽象的父类中;

2、提高了拓展性,将不同的代码放入不同的子类中,通过对子类的扩展增加新的行为;

3、实现了反向控制,通过一个父类调用其子类的操作,通过对子类的扩展增加新的行为。


缺点

1、引入了抽象类,每一个不同的实现都需要一个子类来实现,导致类的个数增加,从而增加了系统实现的复杂度。


使用场景

1、一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现;

2、各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。