“define the skeleton of an algorithm in an operation, deferring some steps to subclasses. templatemethod lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure”。
即模板方法定义一个算法的架构,并将某些步骤推迟到子类中实现。模板方法允许子类在不改变算法架构的情况下,重新定义算法中某些步骤。
为了以更简单的术语描述模板方法,考虑这个场景:假设在一个工作流系统中,为了完成任务,有4个任务必须以给定的执行顺序执行。在这4个任务中,不同工作流系统的实现可以根据自身情况自定义任务的执行内容。
模板方法可以应用在上述场景中:将工作流系统的4个核心任务封装到抽象类当中,如果任务可以被自定义,则将可自定义的任务推迟到子类中实现。
代码实现:
<code>01</code>
<code>/** </code>
<code>02</code>
<code> </code><code>* abstract workflow system </code>
<code>03</code>
<code> </code><code>*/</code>
<code>04</code>
<code>abstract</code> <code>class</code> <code>workflowmanager2{</code>
<code>05</code>
<code>06</code>
<code> </code><code>public</code> <code>void</code> <code>dotask1(){</code>
<code>07</code>
<code>08</code>
<code> </code><code>system.out.println(</code><code>"doing task1..."</code><code>);</code>
<code>09</code>
<code>10</code>
<code> </code><code>}</code>
<code>11</code>
<code>12</code>
<code> </code><code>public</code> <code>abstract</code> <code>void</code> <code>dotask2();</code>
<code>13</code>
<code>14</code>
<code> </code><code>public</code> <code>abstract</code> <code>void</code> <code>dotask3();</code>
<code>15</code>
<code>16</code>
<code> </code><code>public</code> <code>void</code> <code>dotask4(){</code>
<code>17</code>
<code>18</code>
<code> </code><code>system.out.println(</code><code>"doing task4..."</code><code>);</code>
<code>19</code>
<code>20</code>
<code>21</code>
<code>22</code>
<code>}</code>
<code>23</code>
<code>24</code>
<code>25</code>
<code> </code><code>* one of the extensions of the abstract workflow system </code>
<code>26</code>
<code>27</code>
<code>class</code> <code>workflowmanager2impl1 </code><code>extends</code> <code>workflowmanager2{</code>
<code>28</code>
<code>29</code>
<code> </code><code>@override</code>
<code>30</code>
<code> </code><code>public</code> <code>void</code> <code>dotask2(){</code>
<code>31</code>
<code>32</code>
<code> </code><code>system.out.println(</code><code>"doing task2.1..."</code><code>);</code>
<code>33</code>
<code>34</code>
<code>35</code>
<code>36</code>
<code>37</code>
<code> </code><code>public</code> <code>void</code> <code>dotask3(){</code>
<code>38</code>
<code>39</code>
<code> </code><code>system.out.println(</code><code>"doing task3.1..."</code><code>);</code>
<code>40</code>
<code>41</code>
<code>42</code>
<code>43</code>
<code>44</code>
<code>45</code>
<code>46</code>
<code> </code><code>* other extension of the abstract workflow system </code>
<code>47</code>
<code>48</code>
<code>class</code> <code>workflowmanager2impl2 </code><code>extends</code> <code>workflowmanager2{</code>
<code>49</code>
<code>50</code>
<code>51</code>
<code>52</code>
<code>53</code>
<code> </code><code>system.out.println(</code><code>"doing task2.2..."</code><code>);</code>
<code>54</code>
<code>55</code>
<code>56</code>
<code>57</code>
<code>58</code>
<code>59</code>
<code>60</code>
<code> </code><code>system.out.println(</code><code>"doing task3.2..."</code><code>);</code>
<code>61</code>
<code>62</code>
<code>63</code>
<code>64</code>
我们来看看工作流系统如何使用:
<code>public</code> <code>class</code> <code>templatemethodpattern {</code>
<code> </code><code>public</code> <code>static</code> <code>void</code> <code>main(string[] args) {</code>
<code> </code><code>initiateworkflow(</code><code>new</code> <code>workflowmanager2impl1());</code>
<code> </code><code>initiateworkflow(</code><code>new</code> <code>workflowmanager2impl2());</code>
<code> </code><code>static</code> <code>void</code> <code>initiateworkflow(workflowmanager2 workflowmgr){</code>
<code> </code><code>system.out.println(</code><code>"starting the workflow ... the old way"</code><code>);</code>
<code> </code><code>workflowmgr.dotask1();</code>
<code> </code><code>workflowmgr.dotask2();</code>
<code> </code><code>workflowmgr.dotask3();</code>
<code> </code><code>workflowmgr.dotask4();</code>
输出如下所示:
<code>starting the workflow ... the old way</code>
<code>doing task1...</code>
<code>doing task2.</code><code>1</code><code>...</code>
<code>doing task3.</code><code>1</code><code>...</code>
<code>doing task4...</code>
<code>doing task2.</code><code>2</code><code>...</code>
<code>doing task3.</code><code>2</code><code>...</code>
目前为止一切顺利。但是本篇博客的主要关注点不是模板方法模式,而是如何利用java 8的lambda表达式和默认方法实现模板方法模式。我之前已经说过,接口只有在只声明了一个抽象方法的前提下,才可以使用lambda表达式。这个规则在本篇的例子中应这样解释:workflowmanager2只能有一个抽象或者说自定义的任务。
我们可以利用带有默认方法的接口替代抽象类,所以我们的新工作流系统如下所示:
<code>interface</code> <code>workflowmanager{</code>
<code> </code><code>public</code> <code>default</code> <code>void</code> <code>dotask1(){</code>
<code> </code><code>public</code> <code>void</code> <code>dotask2();</code>
<code> </code><code>public</code> <code>default</code> <code>void</code> <code>dotask3(){</code>
<code> </code><code>system.out.println(</code><code>"doing task3..."</code><code>);</code>
<code> </code><code>public</code> <code>default</code> <code>void</code> <code>dotask4(){</code>
现在我们的工作流系统带有一个可自定义的任务2,我们继续往下走,利用lambda表达式处理初始化工作:
<code>public</code> <code>class</code> <code>templatemethodpatternlambda {</code>
<code> </code><code>/** </code>
<code> </code><code>* using lambda expression to create different </code>
<code> </code><code>* implementation of the abstract workflow </code>
<code> </code><code>*/</code>
<code> </code><code>initiateworkflow(()->system.out.println(</code><code>"doing task2.1..."</code><code>));</code>
<code> </code><code>initiateworkflow(()->system.out.println(</code><code>"doing task2.2..."</code><code>));</code>
<code> </code><code>initiateworkflow(()->system.out.println(</code><code>"doing task2.3..."</code><code>));</code>
<code> </code><code>static</code> <code>void</code> <code>initiateworkflow(workflowmanager workflowmgr){</code>
<code> </code><code>system.out.println(</code><code>"starting the workflow ..."</code><code>);</code>
这就是一个lambda表达式应用在模板方法模式中的例子。