写点什么

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

作者:愚公搬代码
  • 2022 年 6 月 04 日
  • 本文字数:2474 字

    阅读完需:约 8 分钟

前言

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

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

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


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

二、使用步骤

角色

1、抽象类(Abstract Class)


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


2、具体类(Concrete Class)


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

示例


命名空间 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!----------------------------------
复制代码


<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">

总结

优点

1、提高代码复用性,可以将相同部分的代码放在抽象的父类中;2、提高了拓展性,将不同的代码放入不同的子类中,通过对子类的扩展增加新的行为;3、实现了反向控制,通过一个父类调用其子类的操作,通过对子类的扩展增加新的行为。

缺点

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

使用场景

1、一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现;2、各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。

发布于: 刚刚阅读数: 3
用户头像

还未添加个人签名 2022.03.01 加入

该博客包括:.NET、Java、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、python、大数据等相关使用及进阶知识。查看博客过程中,如有任何问题,皆可随时沟通。

评论

发布
暂无评论
【愚公系列】2022年06月 二十三种设计模式(二十二)-模板方法模式(Template Method Pattern)_6月月更_愚公搬代码_InfoQ写作社区