小看--模板方法设计模式
模板方法设计模式:就是把两者的公共部分抽取出来当模板,把变化的部分当成扩展点丢出去。
(一)知识点储备
抽象类,抽象方法,虚方法,接口等,知识点理解,请看我的另外一篇博客:http://www.cnblogs.com/gdouzz/p/8387624.html
(二)模板方法设计模式的演变
下面模拟一个银行的客户端,有查询余额,计算利息,显示余额等功能,具体如下:
/// <summary> /// 一个银行的客户端 /// </summary> public class Client { /// <summary> /// 检查用户信息 /// </summary> /// <param name="number"></param> /// <param name="password"></param> /// <returns></returns> public bool CheckUser(int number, string password) { return DateTime.Now < DateTime.Now.AddDays(1); } public void Query(int number, string name, string password) { if (this.CheckUser(number, password)) { double balance = this.QueryBalance(number); double interest = this.CaculateInterest(balance); this.Show(name,balance,interest); } else { Console.WriteLine("用户名和密码不正确"); } } public double QueryBalance(int number) { return new Random().Next(10000,100000); } public double CaculateInterest(double balance) { return balance * 0.03; } /// <summary> /// 展示下 /// </summary> /// <param name="name"></param> /// <param name="balance"></param> /// <param name="interest"></param> public void Show(string name, double balance, double interest) { Console.WriteLine("尊敬的{0}客户,你的账户余额为:{1},利息为{2}", name, balance, interest); } }
假设上面这个是活期存款的,计算利息方法,现在来了个定期存款利息计算方法是0.05;其他的都不变,那么按照我们最简单的做法,那么就去计算利息的方法里面判断一下(if...else..)一下...然后随着银行的业务不断发展,理财业务也来了,除了利息不一样之外,在Show的时候,还应该给人做个提示:“投资有风险,理财需谨慎”;
这个时候,模板方法设计模式,就出来了,根据我们上面的业务特点,我们需要给客户端抽取一个父类出来(这个父类,就是我们的模板,这个父类也是很有意思)。
/// <summary> /// 银行客户端模拟 /// </summary> public abstract class AbstractClient { /// <summary> /// 登陆查询功能 /// </summary> /// <param name="id"></param> /// <param name="name"></param> /// <param name="password"></param> public void Query(int id, string name, string password) { if (this.CheckUser(id, password)) { double balance = this.QueryBalance(id); double interest = this.CalculateInterest(balance); this.Show(name, balance, interest); } else { Console.WriteLine("账户密码错误"); } } /// <summary> /// 用户检测 /// </summary> /// <param name="id"></param> /// <param name="password"></param> /// <returns></returns> public bool CheckUser(int id, string password) { return DateTime.Now < DateTime.Now.AddDays(1); } /// <summary> /// 查询余额 /// </summary> /// <param name="id"></param> /// <returns></returns> public double QueryBalance(int id) { return new Random().Next(10000, 1000000); } /// <summary> /// 获取利率,计算利息 /// 定期 0.05 /// 活期 0.03 /// 子类都有这个方法 但是各不相同 约束,所以这里采用了抽象方法。 /// </summary> /// <param name="balance"></param> /// <returns></returns> public abstract double CalculateInterest(double balance); /// <summary> /// 这个展示的方法,定期查询类和活期查询类都一样,只是理财类不一致,所以采用了虚方法 /// </summary> /// <param name="name"></param> /// <param name="balance"></param> /// <param name="interest"></param> public virtual void Show(string name, double balance, double interest) { Console.WriteLine("尊敬的{0}客户,你的账户余额为:{1},利息为{2}", name, balance, interest); } }
之后的代码,就不贴出来了,模板方法设计模式是不是感觉特别简单,整个流程都是那么直白,不像访问者模式等等那么绕弯子。
(三)题外话
设计模式的来源是根据我们生活中常见的场景,每一个设计模式都是从场景出发的。模板方法设计模式,虽然简单,但是它的应用无处不在,只是我们平常可能都忽略罢了。就是一句话:把通用的东西封装起来,把变化的东西丢出去,就像平时我们自己做框架也是的,把通用的部分封装起来,留下扩展点。希望能给大家一点共鸣。
终极目标:世界大同