模板方法模式
本片博客将介绍模板方法模式,模板方法模式是最简单的行为型设计模式,它是一种类行为模式,在其结构中只存在父类和子类之间的继承关系。通过使用模板方法模式,可以将一些复杂流程的实现步骤封装在一系列基本方法中,在抽象父类中提供了一个被称为模板方法的方法用于定义这些基本方法的次序,并通过其子类来覆盖某些步骤,从而使得相同的算法框架可以有不同的执行结果。
模式分类
行为型设计模式。
模式产生的原因
在现实生活中,很多事情都包含几个实现步骤,例如请客吃饭,无论吃什么,一般都包含点单,吃东西,买单等几个步骤,通常情况下这几个步骤的次序是:点单——》吃东西——》买单。在这三个步骤中,点单和买单大同小异,最大的区别在于第二步——吃什么,吃面条还是吃满汉全席可是大不相同的。
在软件开发中,开发人员有时也会遇到类似的情况,某个方法的实现需要多个步骤,其中有些步骤是固定的,有些则是不固定的,存在可变性。为了提高代码的可用性和系统的灵活性,可以使用一种称为模板方法模式的设计模式来对这种情况进行设计。在模板方法中将实现功能的每一个方法称为基本方法,而调用这些基本方法并决定其执行次序的方法被称为模板方法。我们可以将相同的代码放在父类,而变化的代码则有子类实现,这样就可以解决上面吃什么的问题了。
模式类图
由上图可知,模板方法模式由以下2个角色构成。
AbstractClass(抽象父类):
在抽象类中会定义一系列的基本操作,这些操作可以是具体的也可以是抽象的,每一个方法都对应了算法步骤中的一步,在其子类中可以重定义火实现这些步骤。同时,在抽象类中实现了一个模板方法,用于定义一个算法的框架。
ConcreteClass(具体子类):
是抽象类的子类,用于在子类中实现父类中声明的抽象基本操作,及完成子类特定算法的步骤,也可以覆盖在父类中已经实现的具体基本操作。
代码实现
例子:某软件公司要为某银行的业务支撑系统开发一个利息计算模块,计算流程如下:
- 系统根据账号和密码验证用户信息,如果用户信息错误,则系统显示出错信息。
- 如果信息正确,则更具用户类型的不同使用不同的利息计算公式计算利息。
- 系统显示利息。
试使用模板方法模式模拟此系统。
Account类:
using System;
namespace TemplateMethod.TemplateMethod.Example
{
public abstract class Account
{
public string Name { get; set; }
public string Password { get; set; }
public Account(string name, string password)
{
Name = name;
Password = password;
}
/// <summary>
/// 模板方法
/// </summary>
/// <param name="name"></param>
/// <param name="password"></param>
public void Execute(string name, string password)
{
if (Check(name, password))
{
Console.WriteLine(Calculate());
}
else
{
Console.WriteLine($"错误");
}
}
public bool Check(string name, string password)
{
if (Name.Equals(name) && Password.Equals(password))
{
return true;
}
else
{
return false;
}
}
public abstract float Calculate();
}
}
SavingAccount类:
namespace TemplateMethod.TemplateMethod.Example
{
public class SavingAccount : Account
{
public SavingAccount(string name, string password) : base(name, password)
{
}
public override float Calculate()
{
return 1f;
}
}
}
CurrentAccount类:
namespace TemplateMethod.TemplateMethod.Example
{
public class CurrentAccount : Account
{
public CurrentAccount(string name, string password) : base(name, password)
{
}
public override float Calculate()
{
return 0f;
}
}
}
Program类:
using TemplateMethod.TemplateMethod.Example;
namespace TemplateMethod
{
internal class Program
{
public static void Main(string[] args)
{
Account xiaoming = new CurrentAccount("xiaoming", "123456");
xiaoming.Execute("xiaoming", "123456");
xiaoming.Execute("123","123");
Account xiaohong = new SavingAccount("xiaohong", "123456");
xiaohong.Execute("xiaohong", "123456");
xiaohong.Execute("123","123");
}
}
}
模板方法模式总结
模板方法模式优点:
- 在父类中形式化的定义了一个算法,而又他的子类去处理实现的细节,在子类中实现详细的处理算法时并不会改变算法中步骤的执行顺序。
- 模板方法是一种代码复用技术,在类库设计中尤为重要,他提取类库中的公共行为,,并通过子类来实现不同行为。鼓励适当地使用继承来实现代码复用。
模板方法模式缺点:
- 需要为每一种基本方法的不同实现提供一个子类,这将会导致系统的类的个数快速增加,可通过桥接模式来优化。