天天看點

采用Java 8中Lambda表達式和預設方法的模闆方法模式

“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(()-&gt;system.out.println(</code><code>"doing task2.1..."</code><code>));</code>

<code>        </code><code>initiateworkflow(()-&gt;system.out.println(</code><code>"doing task2.2..."</code><code>));</code>

<code>        </code><code>initiateworkflow(()-&gt;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表達式應用在模闆方法模式中的例子。