“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表達式應用在模闆方法模式中的例子。