经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
一个最简单的设计模式-模板方法
来源:cnblogs  作者:浪人~  时间:2019/7/15 8:57:56  对本文有异议

《Head First设计模式》已经读了不止一遍,但是始终没有进行系统的进行总结。所以近期开始总结设计模式相关的知识,从模板方法模式开始,因为是一个我认为是最简单的设计模式。(推荐视频资源23个设计模式

提出&解决问题

提出问题

实现制作咖啡功能。且制作咖啡需要四个步骤 :

  1. 烧水
  2. 冲泡咖啡
  3. 倒入杯中
  4. 加糖

代码实现

  1. /**
  2. * 一杯加糖咖啡
  3. *
  4. * @author Jann Lee
  5. * @date 2019-07-14 18:37
  6. */
  7. public class Coffee {
  8. /**
  9. * 制作一杯加糖咖啡
  10. */
  11. public void prepareRecipe() {
  12. boilWater();
  13. steepTeaBag();
  14. portInCup();
  15. addLemon();
  16. }
  17. /**
  18. * step1: 烧水
  19. */
  20. private void boilWater() {
  21. System.out.println("烧水...");
  22. }
  23. /**
  24. * step2:冲泡咖啡
  25. */
  26. private void steepTeaBag() {
  27. System.out.println("冲泡咖啡...");
  28. }
  29. /**
  30. * step3: 倒入杯中
  31. */
  32. private void portInCup() {
  33. System.out.println("倒入杯中...");
  34. }
  35. /**
  36. * step4: 加糖
  37. */
  38. private void addLemon() {
  39. System.out.println("加糖...");
  40. }

再次提出问题此时此刻我需要一杯柠檬茶呢?【烧水,冲泡茶包,倒入杯中,加柠檬】

这个问题当然很简单,我们只需要如法炮制即可。

  1. public class Tea {
  2. /**
  3. * 制作一杯柠檬茶
  4. */
  5. public void prepareRecipe(){
  6. boilWater();
  7. brewCoffeeGrinds();
  8. portInCup();
  9. addSugarAndMilk();
  10. }
  11. /**
  12. * step1: 烧水
  13. */
  14. private void boilWater() {
  15. System.out.println("烧水...");
  16. }
  17. /**
  18. * step2:冲泡咖啡
  19. */
  20. private void brewCoffeeGrinds() {
  21. System.out.println("冲泡茶包...");
  22. }
  23. /**
  24. * step3: 倒入杯中
  25. */
  26. private void portInCup() {
  27. System.out.println("倒入杯中...");
  28. }
  29. /**
  30. * step4: 加柠檬
  31. */
  32. private void addSugarAndMilk() {
  33. System.out.println("加入柠檬片...");
  34. }
  35. }

思考

? 如果此时我们又需要一杯不加柠檬的茶,加奶的咖啡...,当然我们可以按照上面方式重新依次实现即可。但是如果你是一个有经验的程序员,或者你学习过设计模式。你可能会发现以上功能实现的步骤/流程固定,当需求发生变化时,只有小部分步骤有所改变

优化代码

根据面向对象程序的特点,既抽象,封装,继承,多态。我们可以对代码进行抽象,将公共代码提取到基类。我们将咖啡和茶抽象成咖啡因饮料,将其中相同的两步,烧水和倒入杯中再父类中实现,将冲泡和添加调料延迟到子类。

  1. 定义一个基类
  1. public abstract class CafeineBeverage {
  2. /**
  3. * 制作一杯咖啡因饮料
  4. */
  5. public void prepareRecipe() {
  6. boilWater();
  7. brew();
  8. portInCup();
  9. addCondiments();
  10. }
  11. /**
  12. * step1: 烧水
  13. */
  14. private void boilWater() {
  15. System.out.println("烧水...");
  16. }
  17. /**
  18. * step2:冲泡
  19. */
  20. protected abstract void brew();
  21. /**
  22. * step3: 入杯中
  23. */
  24. private void portInCup() {
  25. System.out.println("倒入杯中...");
  26. }
  27. /**
  28. * step4: 加调料
  29. */
  30. protected abstract void addCondiments();
  31. }
  1. // 一杯加糖咖啡
  2. public class CoffeeBeverage extends CafeineBeverage{
  3. @Override
  4. protected void brew() {
  5. System.out.println("冲泡咖啡...");
  6. }
  7. @Override
  8. protected void addCondiments() {
  9. System.out.println("加糖...");
  10. }
  11. }
  1. // 一杯柠檬茶
  2. public class TeaBeverage extends CafeineBeverage {
  3. @Override
  4. protected void brew() {
  5. System.out.println("冲泡茶包...");
  6. }
  7. @Override
  8. protected void addCondiments() {
  9. System.out.println("加柠檬...");
  10. }
  11. }

模板方法模式

如果按以上方式对代码进行了优化,其实就实现了模板方法模式。一下是模板方法模式相关概念。

动机

  • 在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但是各个子步骤却有很多改变的需求,或者由于固有的原因(比如框架与应用之间的关系)而无法和任务的整体结构同时实现
  • 如何在确定稳定的操作结构的前提下,来灵活应对各个子步骤的变化或者晚期实现需求?

定义

定义一个操作中算法的骨架(稳定),而将一些步骤延迟(变化)到子类。Template Method使得子类可以不改变(复用)一个算法的结构,即可重新定义(override)该算法的特定步骤。

要点总结

  • Template Method是一种非常基础性的设计模式,在面向对象系统中,有着大量的应用。他用最简洁的机制(抽象类的多态,为很多应用框架提供了灵活的扩展点,是代码复用方面最基本实现结构)
  • 除了可以灵活应对子步骤的变化外,“不要调用我,让我来调用你”的反向控制结构是Template Method的典型应用
  • 在具体实现方面,被Template Method调用得虚方法可以有实现,也可以没有实现(抽象方法),但一般推荐设置为protected方法

类图:

个人博客网站(正在建设中)

原文链接:http://www.cnblogs.com/liqiangchn/p/11186438.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号