古いルーチンでは、最初に定義を確認します。アルゴリズムのスケルトンを定義し、サブクラスへのいくつかのステップを遅らせます。テンプレートメソッドを使用すると、サブクラスはアルゴリズムの構造を変更せずにアルゴリズムのステップを再定義できます。
定義を簡単に見ると、テンプレートメソッドはアルゴリズムのステップを定義し、サブクラスが1つ以上のステップの実装を提供できるようにします。定義はかなり明確ですが、会社の仕事の状況を示す例を次に示します(娯楽の場合のみ、類似点がある場合はチェックインしてください)。簡単に説明すると、会社にはプログラマー、テスター、人事、プロジェクトマネージャーなどがいます。以下のテンプレートメソッドモードを使用して、すべての担当者の作業状況を記録します。
まず、スーパークラスを取り上げます。workOneDayメソッドはスーパークラスで定義され、アルゴリズムのスケルトンとして設定されます。
package com.zhy.pattern.template;
public abstract class Worker
{
protected String name;
public Worker(String name)
{
this.name = name;
}
/**
* 记录一天的工作
*/
public final void workOneDay()
{
System.out.println("-----------------work start ---------------");
enterCompany();
computerOn();
work();
computerOff();
exitCompany();
System.out.println("-----------------work end ---------------");
}
/**
* 工作
*/
public abstract void work();
/**
* 关闭电脑
*/
private void computerOff()
{
System.out.println(name + "关闭电脑");
}
/**
* 打开电脑
*/
private void computerOn()
{
System.out.println(name + "打开电脑");
}
/**
* 进入公司
*/
public void enterCompany()
{
System.out.println(name + "进入公司");
}
/**
* 离开公司
*/
public void exitCompany()
{
System.out.println(name + "离开公司");
}
}
次の手順を含む、仕事に行くためのスケルトン(アルゴリズム)を定義します:
a。会社を入力します
b。コンピュータの電源を入れます
c。仕事の状況
d。コンピュータの電源を切ります
e。会社を辞める
スーパークラスにa、b、d、eを実装しており、サブクラスは、毎日の作業状況を記録するための作業の抽象メソッドのみを実装していることがわかります。以下のタイプのdiaosiが許可されます。
プログラマー:
package com.zhy.pattern.template;
public class ITWorker extends Worker
{
public ITWorker(String name)
{
super(name);
}
@Override
public void work()
{
System.out.println(name + "写程序-测bug-fix bug");
}
}
人事:
package com.zhy.pattern.template;
public class HRWorker extends Worker
{
public HRWorker(String name)
{
super(name);
}
@Override
public void work()
{
System.out.println(name + "看简历-打电话-接电话");
}
}
テスター:
package com.zhy.pattern.template;
public class QAWorker extends Worker
{
public QAWorker(String name)
{
super(name);
}
@Override
public void work()
{
System.out.println(name + "写测试用例-提交bug-写测试用例");
}
}
プロジェクトマネージャ:
package com.zhy.pattern.template;
public class ManagerWorker extends Worker
{
public ManagerWorker(String name)
{
super(name);
}
@Override
public void work()
{
System.out.println(name + "打dota...");
}
}
以下でテストしてみましょう。
package com.zhy.pattern.template;
public class Test
{
public static void main(String[] args)
{
Worker it1 = new ITWorker("鸿洋");
it1.workOneDay();
Worker it2 = new ITWorker("老张");
it2.workOneDay();
Worker hr = new HRWorker("迪迪");
hr.workOneDay();
Worker qa = new QAWorker("老李");
qa.workOneDay();
Worker pm = new ManagerWorker("坑货");
pm.workOneDay();
}
}
出力結果:
-----------------work start ---------------
鸿洋进入公司
鸿洋打开电脑
鸿洋写程序-测bug-fix bug
鸿洋关闭电脑
鸿洋离开公司
-----------------work end ---------------
-----------------work start ---------------
迪迪进入公司
迪迪打开电脑
迪迪看简历-打电话-接电话
迪迪关闭电脑
迪迪离开公司
-----------------work end ---------------
-----------------work start ---------------
老李进入公司
老李打开电脑
老李写测试用例-提交bug-写测试用例
老李关闭电脑
老李离开公司
-----------------work end ---------------
-----------------work start ---------------
坑货进入公司
坑货打开电脑
坑货打dota...
坑货关闭电脑
坑货离开公司
-----------------work end ---------------
おめでとうございます。デザインパターン、テンプレートメソッドパターンを学びました。
テンプレートメソッドパターンのクラス図とプログラムのクラス図を見てみましょう。
テンプレートメソッドでフックをオプションで設定することもできます。たとえば、プログラマーが退職した時間を記録したい場合は、スーパークラスにフックを追加できます。
public boolean isNeedPrintDate()
{
return false;
}
/**
* 离开公司
*/
public void exitCompany()
{
if (isNeedPrintDate())
{
System.out.print(new Date().toLocaleString()+"-->");
}
System.out.println(name + "离开公司");
}
isNeedPrintDateメソッドがスーパークラスに追加され、時間を出力せずにデフォルトでfalseを返します。特定のサブクラスが印刷時間を呼び出す必要がある場合は、フックメソッドをオーバーライドしてtrueを返すことができます。たとえば、プログラムはこのメソッドをコピーしました。
package com.zhy.pattern.template;
public class ITWorker extends Worker
{
public ITWorker(String name)
{
super(name);
}
@Override
public void work()
{
System.out.println(name + "写程序-测bug-fix bug");
}
@Override
public boolean isNeedPrintDate()
{
return true;
}
}
最後に、テスト結果を見てください。
-----------------work start ---------------
鸿洋进入公司
鸿洋打开电脑
鸿洋写程序-测bug-fix bug
鸿洋关闭电脑
2014-5-19 19:17:05-->鸿洋离开公司
-----------------work end ---------------
まあ、フックについては、スーパークラスはデフォルトの実装または空の実装を提供でき、サブクラスは要件に応じてオーバーライドするかしないかを指定できます。
最近、私はテンプレートメソッドモードを使用して別のクローラープログラムを作成しました。
要件の分析:プログラムは、20の特定のWebサイトのデータをクロールする必要があります。各Webサイトページから返される結果データは異なり、URLは異なります。パラメーターは異なります。ただし、クロールプロセスは同じです。
だから私はこのように設計しました:
a。Ruleクラスを定義します(以下を含みます:url、params、request_method、および[セレクターに従って]どのデータを返すか)
b。ルールを使用してデータを取得する
c。データを処理する
上記の3つのステップでアルゴリズムのスケルトンを定義しました。bはスーパークラスの実装で、aとcはサブクラスによって実現されます。
package com.zhy.pattern.template;
public abstract class AbsExtractInfo
{
/**
* 抓取的算法骨架
*/
public void extract()
{
Rule rule = generateRule() ;
List<Element> eles = getInfosByRule(rule);
dealResult(eles);
}
/**
* 生成一个Rule
* @return
*/
public abstract Rule generateRule();
/**
* 抓取的实现
* @param rule
* @return
*/
private List<Element> getInfosByRule(Rule rule)
{
// the implements omitted
}
/**
* 处理抓取的结果
* @param results
*/
public void dealResult(List<Element> results);
}
それらの中で、GenerateRuleメソッドは、たまたまファクトリパターンの抽象メソッドパターンです(オブジェクトを作成するためのインターフェイスを定義しますが、サブクラスはインスタンス化するクラスを決定します。ファクトリメソッドパターンは、クラスのインスタンス化のプロセスをサブクラスに延期します)。 、忘れた場合は、デザインパターンファクトリーパターンを確認できます。
最後に、メッセージを残してください。