经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
C#设计模式-模板方法模式(Template Method)
来源:cnblogs  作者:Tynam.Yang  时间:2020/11/9 16:08:05  对本文有异议

概念

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

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

特点

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

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

模式结构

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

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

应用场景

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

实现

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

  1. using System;
  2. namespace 模板模式
  3. {
  4. class EntryProcess
  5. {
  6. static void Main(string[] args)
  7. {
  8. SamsungEntryProcess samsung = new SamsungEntryProcess();
  9. HuaweiEntryProcess huawei = new HuaweiEntryProcess();
  10. samsung.JoiningCompany();
  11. huawei.JoiningCompany();
  12. Console.Read();
  13. }
  14. }
  15. // 抽象类,入职流程
  16. public abstract class TemplateEntryProcess
  17. {
  18. // 模板方法,不要把模版方法定义为 Virtual 或 abstract 方法,避免被子类重写,防止更改流程的执行顺序
  19. public void JoiningCompany()
  20. {
  21. this.entryCompany(); // 进入公司
  22. this.preparationForEntry(); // 入职前准备,整理衣帽等
  23. this.registrationForEmployment(); // 入职报到
  24. this.entryProcedures(); // 办理入职手续
  25. this.inductionTraining(); // 入职培训
  26. this.evaluationOfConversion(); // 转正评估
  27. this.entryOver(); // 入职结束,进入岗位
  28. }
  29. public abstract void entryCompany();
  30. public void preparationForEntry()
  31. {
  32. Console.WriteLine("做准备,整理衣帽等;");
  33. }
  34. public void registrationForEmployment()
  35. {
  36. Console.WriteLine("入职报到;");
  37. }
  38. public void entryProcedures()
  39. {
  40. Console.WriteLine("办理入职手续;");
  41. }
  42. public void inductionTraining()
  43. {
  44. Console.WriteLine("进行入职培训;");
  45. }
  46. public void evaluationOfConversion()
  47. {
  48. Console.WriteLine("完成入职前培训,进行转正评估;");
  49. }
  50. public void entryOver()
  51. {
  52. Console.WriteLine("入职流程完成,进入岗位。");
  53. }
  54. }
  55. // 具体子类,三星入职
  56. public class SamsungEntryProcess: TemplateEntryProcess
  57. {
  58. public override void entryCompany()
  59. {
  60. Console.WriteLine("进入三星公司");
  61. }
  62. }
  63. // 具体子类,华为入职
  64. public class HuaweiEntryProcess: TemplateEntryProcess
  65. {
  66. public override void entryCompany()
  67. {
  68. Console.WriteLine("进入华为公司");
  69. }
  70. }
  71. }

执行后结果

  1. 进入三星公司
  2. 做准备,整理衣帽等;
  3. 入职报到;
  4. 办理入职手续;
  5. 进行入职培训;
  6. 完成入职前培训,进行转正评估;
  7. 入职流程完成,进入岗位。
  8. 进入华为公司
  9. 做准备,整理衣帽等;
  10. 入职报到;
  11. 办理入职手续;
  12. 进行入职培训;
  13. 完成入职前培训,进行转正评估;
  14. 入职流程完成,进入岗位。

原文链接:http://www.cnblogs.com/tynam/p/13900280.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号