ToB企服应用市场:ToB评测及商务社交产业平台

标题: 模板模式 [打印本页]

作者: 光之使者    时间: 2023-10-6 07:20
标题: 模板模式
模板模式

案例引入

制作豆浆问题

要求:
1.制作豆浆流程 选材->添加配料->浸泡->放到豆浆机打碎。
2.通过添加不同配料,可以制作出不同口味的豆浆。
3.选材,浸泡和放到豆浆机打碎这些步骤对于制作每种口味的豆浆都是一样的。
4.请使用模板模式,完成。(因为模板方法模式,简单,就直接写了)
基本介绍

原理类图


对类图的说明
1.AbstractClass抽象类,类中实现了模板方法,定义了算法的骨架,其他的抽象方法由具体子类去实现,如operation2,3,4方法
2.ConcreteClass 实现抽象方法operation2,3,4,以完成算法中子类特定的步骤。
模板模式实现制作豆浆案例

案例uml类图


代码实现
  1. /**
  2. * @author 长名06
  3. * @version 1.0
  4. * 豆浆父类,模板类
  5. */
  6. public abstract class SoyaMilk {
  7.     public final void make(){
  8.         select();
  9.         add();
  10.         soak();
  11.         beat();
  12.     }
  13.     /**
  14.      * 选材
  15.      */
  16.     public void select(){
  17.         System.out.println("第一步,选择黄豆作为材料");
  18.     }
  19.     /**
  20.      * 添加配料
  21.      */
  22.     public abstract void add();
  23.     /**
  24.      * 浸泡
  25.      */
  26.     public void soak(){
  27.         System.out.println("第三步,黄豆和配料开始浸泡,需要3小时");
  28.     }
  29.     /**
  30.      * 打碎
  31.      */
  32.     public void beat(){
  33.         System.out.println("第四步,黄豆和配料放到豆浆机去打碎");
  34.     }
  35. }
  36. /**
  37. * @author 长名06
  38. * @version 1.0
  39. */
  40. public class RedBeanSoyaMilk extends SoyaMilk{
  41.     @Override
  42.     public void add() {
  43.         System.out.println("第二步,加入上好的红豆");
  44.     }
  45. }
  46. /**
  47. * @author 长名06
  48. * @version 1.0
  49. */
  50. public class PeanutSoyaMilk extends SoyaMilk {
  51.     @Override
  52.     public void add() {
  53.         System.out.println("第二步,加入上好的花生");
  54.     }
  55. }
  56. /**
  57. * @author 长名06
  58. * @version 1.0
  59. */
  60. public class Client {
  61.     public static void main(String[] args) {
  62.         //制作红豆豆浆
  63.         SoyaMilk redBeanSoyaMilk = new RedBeanSoyaMilk();
  64.         redBeanSoyaMilk.make();
  65.         System.out.println("----------");
  66.         //制作花生豆浆
  67.         SoyaMilk peanutSoyaMilk = new PeanutSoyaMilk();
  68.         peanutSoyaMilk.make();
  69.     }
  70. }
复制代码
模板模式的钩子方法

  1. /**
  2. * @author 长名06
  3. * @version 1.0
  4. * 豆浆父类,模板类
  5. */
  6. public abstract class SoyaMilk {
  7.     public final void make(){
  8.         select();
  9.         if(isAdd()){
  10.             add();
  11.         }
  12.         soak();
  13.         beat();
  14.     }
  15.     /**
  16.      * 选材
  17.      */
  18.     public void select(){
  19.         System.out.println("第一步,选择黄豆作为材料");
  20.     }
  21.     /**
  22.      * 添加配料
  23.      */
  24.     public abstract void add();
  25.     /**
  26.      * 浸泡
  27.      */
  28.     public void soak(){
  29.         System.out.println("第三步,黄豆和配料开始浸泡,需要3小时");
  30.     }
  31.     /**
  32.      * 打碎
  33.      */
  34.     public void beat(){
  35.         System.out.println("第四步,黄豆和配料放到豆浆机去打碎");
  36.     }
  37.     /**
  38.      * 是否需要添加原料,这样设计,可以设置为,子类空实现add步骤,但是不进行添加
  39.      * 勾子方法,由这个方法的返回值,判断是否执行那个需要被子类重写的方法,钩子方法
  40.      * 是可以被子类继承,由具体子类决定是否执行
  41.      * @return
  42.      */
  43.     public boolean isAdd(){
  44.         return true;
  45.     }
  46. }
  47. /**
  48. * @author 长名06
  49. * @version 1.0
  50. */
  51. public class RedBeanSoyaMilk extends SoyaMilk {
  52.     @Override
  53.     public void add() {
  54.         System.out.println("第二步,加入上好的红豆");
  55.     }
  56. }
  57. /**
  58. * @author 长名06
  59. * @version 1.0
  60. * 纯豆浆
  61. */
  62. public class PureBeanSoyaMilk extends SoyaMilk{
  63.     @Override
  64.     public void add() {
  65.         System.out.println("第二步,制作纯豆浆,不加任何配料");
  66.     }
  67.     @Override
  68.     public boolean isAdd() {
  69.         return !super.isAdd();//不执行第二步
  70.     }
  71. }
  72. /**
  73. * @author 长名06
  74. * @version 1.0
  75. * 花生豆浆
  76. */
  77. public class PeanutSoyaMilk extends SoyaMilk {
  78.     @Override
  79.     public void add() {
  80.         System.out.println("第二步,加入上好的花生");
  81.     }
  82. }
  83. /**
  84. * @author 长名06
  85. * @version 1.0
  86. */
  87. public class Client {
  88.     public static void main(String[] args) {
  89.         //制作红豆豆浆
  90.         SoyaMilk redBeanSoyaMilk = new RedBeanSoyaMilk();
  91.         redBeanSoyaMilk.make();
  92.         System.out.println("----------");
  93.         //制作花生豆浆
  94.         SoyaMilk peanutSoyaMilk = new PeanutSoyaMilk();
  95.         peanutSoyaMilk.make();
  96.         System.out.println("----------");
  97.         //制作纯豆浆
  98.         SoyaMilk pureBeanSoyaMilk = new PureBeanSoyaMilk();
  99.         pureBeanSoyaMilk.make();
  100.     }
  101. }
复制代码
注意事项和细节

模板模式在Spring框架中的源码分析
  1.     //该方法是AbstractApplicationContext类中的方法,类似模板模式中的模板方法(定义骨架的方法),案例中的make()
  2.     @Override
  3.         public void refresh() throws BeansException, IllegalStateException {
  4.         //定义容器初始化的模板,空方法由子类实现,由子类调用完成,容器的初始化,AbstractApplicationContext的子类有AbstractRefreshableApplicationContext和              
  5.         // GenericApplicationContext
  6.                 synchronized (this.startupShutdownMonitor) {
  7.                         // Prepare this context for refreshing.
  8.                         prepareRefresh();
  9.                         // Tell the subclass to refresh the internal bean factory.
  10.                         ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
  11.                         // Prepare the bean factory for use in this context.
  12.                         prepareBeanFactory(beanFactory);
  13.                         try {
  14.                                 // Allows post-processing of the bean factory in context subclasses.
  15.                                 postProcessBeanFactory(beanFactory);
  16.                                 // Invoke factory processors registered as beans in the context.
  17.                                 invokeBeanFactoryPostProcessors(beanFactory);
  18.                                 // Register bean processors that intercept bean creation.
  19.                                 registerBeanPostProcessors(beanFactory);
  20.                                 // Initialize message source for this context.
  21.                                 initMessageSource();
  22.                                 // Initialize event multicaster for this context.
  23.                                 initApplicationEventMulticaster();
  24.                                 // Initialize other special beans in specific context subclasses.
  25.                                 onRefresh();
  26.                                 // Check for listener beans and register them.
  27.                                 registerListeners();
  28.                                 // Instantiate all remaining (non-lazy-init) singletons.
  29.                                 finishBeanFactoryInitialization(beanFactory);
  30.                                 // Last step: publish corresponding event.
  31.                                 finishRefresh();
  32.                         }
  33.                         catch (BeansException ex) {
  34.                                 if (logger.isWarnEnabled()) {
  35.                                         logger.warn("Exception encountered during context initialization - " +
  36.                                                         "cancelling refresh attempt: " + ex);
  37.                                 }
  38.                                 // Destroy already created singletons to avoid dangling resources.
  39.                                 destroyBeans();
  40.                                 // Reset 'active' flag.
  41.                                 cancelRefresh(ex);
  42.                                 // Propagate exception to caller.
  43.                                 throw ex;
  44.                         }
  45.                         finally {
  46.                                 // Reset common introspection caches in Spring's core, since we
  47.                                 // might not ever need metadata for singleton beans anymore...
  48.                                 resetCommonCaches();
  49.                         }
  50.                 }
  51.         }
  52.     //该方法是AbstractApplicationContext类中的方法
  53.     protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
  54.                 refreshBeanFactory();//这个方法,在本类中是抽象方法,由子类去实现
  55.                 ConfigurableListableBeanFactory beanFactory = getBeanFactory();
  56.                 if (logger.isDebugEnabled()) {
  57.                         logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
  58.                 }
  59.                 return beanFactory;
  60.         }
  61.     //该方法是AbstractApplicationContext类中的方法 类似模板模式中的抽象方法,需要子类实现,案例中的add()方法
  62.     protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;
复制代码
只是为了记录自己的学习历程,且本人水平有限,不对之处,请指正。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4