⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 templatemethod.htm

📁 DesignPattern基于Java方面最好的书
💻 HTM
字号:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>





  
  
  
  
  
  <link rel="stylesheet" href="css/stdlayout.css" type="text/css">





  
  
  
  
  
  <link rel="stylesheet" href="css/print.css" type="text/css">





  
  
  
  
  
  <meta content="text/html; charset=gb2312" http-equiv="content-type">





  
  
  
  
  
  <title>Template Method 模式</title>
</head>


<body>





<h3><a href="http://caterpillar.onlyfun.net/GossipCN/index.html">From
Gossip@caterpillar</a></h3>





<h1><a href="CppGossip.html">Design Pattern:&nbsp;Template Method 模式</a></h1>

不要将设计模式想得高不可攀,好像高手才会使用的东西,事实上如果您在下手程式之前,能稍稍对程式作个分析规划,或多或少都会用到一些模式了,模式不是教条,它只是前人的经验成果,而 Gof 的书则是择前人之精华持续改进而来罢了。<br>
<br>
Template Method模式就是一个很简单的模式,但可能是使用最广泛的模式,也许您也一直在使用这样的模式,看它的 UML 类别结构图就知道了:<br>
<div style="text-align: center;"><img style="width: 338px; height: 205px;" alt="TemplateMethod" title="TemplateMethod" src="images/templateMethod-1.jpg"><br>
</div>
<br>
仅仅是抽象类别与具体类别实作的关系而已,有些人常问抽象类别与介面的区别为何,Template Method模式可以提供其中一个答案,例如:<br>
<ul>
  <li>AbstractClass.java</li>
</ul>
<pre>public abstract class AbstractClass { <br>    public void templateMethod() { <br>        // step by step template to solve something <br>        // implementor should follow those step <br>        opStep1(); <br>        opStep2(); <br>        opStep3(); <br>    } <br><br>    public abstract void opStep1(); <br>    public abstract void opStep2(); <br>    public abstract void opStep3(); <br>} <br></pre>
<br>
<ul>
  <li>ConcreteClass.java</li>
</ul>
<pre>public class ConcreteClass extends AbstractClass { <br>    public abstract void opStep1() { <br>        // implement the real operation <br>    } <br><br>    public abstract void opStep2() { <br>        // implement the real operation <br>    } <br><br>    public abstract void opStep3() { <br>        // implement the real operation <br>    } <br>}</pre>
<br>
对于一些程式而言,我们希望规定一些处理的步骤、流程或骨架,就像是上例中的step1到step3一样,至于流程中的step1到step3如何实作并不规定,而留给实作的人自行决定,这就是Template Method模式的目的。<br>
<br>
抽象类别与介面的差别之一,也正在于抽象类别可以先实作其中一些方法,而介面则是完全仅规定接口,使用Template Method模式就可以看出两者之间在应用上的一个差别。<br>
<br>
仅以step1到step3这样的操作来看Template Method模式,似乎彰显示不出其实作骨架,而将实作部份留待子类的实用性,在 Gof
书中所举的例子是与 Factory Method 模式
结合的一个例子;通常开启一个档案的流程是相似的,例如文字档或二进位档,不外乎检查档案是否可开启、读取档案、设定显示等流程,可以使用
Template Method模式来规范这个流程:&nbsp;<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;public abstract class Application { </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp; // ..... </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp; public void openDocument(String name) { </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Template Method </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!canOpenDocument(name)) { // unable to open file </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // show error message, throw exception </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return; </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Document doc = createDocument(); // Factory Method </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(doc != null) { </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _docs.addDocument(doc); </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Template Method </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; aboutToOpenDocument(doc); </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; doc.open(); </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; doc.doRead(); </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp; } </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp; // Factory Method </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp; public abstract Document createDocument(); </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp; // Template Method </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp; public abstract boolean canOpenDocument(String name); </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp; public abstract void aboutToOpenDocument(Document doc); </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;} </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;public class MyApplication extends Application { </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp; // implement Factory Method </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp; public void Document createDocument() { </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new MyDocument(); </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp; } </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp; // implement Template Method </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp; public void boolean canOpenDocument(String name) { </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // implemented code here </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp; } </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp; public void aboutToOpenDocument(Document doc) { </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // implemented code here </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;&nbsp;&nbsp; } </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">&nbsp;}</span><br>
</div>
&nbsp;<br>
<a href="FactoryMethod.htm">Factyro Method模式</a>将实际要创建的物件推迟至子类中决定,而
Template
Method模式则是将流程框架的实作留待子类来解决,事实上在这个例子中,您也可以将createDocument()看作是Template
Method模式中的一个方法,从物件创建的角度来看它是Factory Method,而从流程框架的角度来看,它则是Template
Method模式的一个方法实作。<br>
<br>





</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -