最初の生命の例に、当社の経営に基づいて、テンプレートモードの原則の話の前に。茶屋は自動紅茶とコーヒーのプログラムを開発する必要があります。
チュートリアルのテンプレートモード「凱歌学習デザインパターン」シリーズ:この記事はから来ています
コーヒーや紅茶を見てみましょう手順は次のとおりです。
私たちが達成するためにコードを書くマップによると:
コーヒーの種類、以下に示すように:
次のように図の茶クラスは次のとおりです。
テストカテゴリ:
結果:
非常にシンプル。また、書くのは非常に簡単です。非常に明確に書かれました。
上記の図から見ることができる、2つのプロセスがほぼ同じルーチン(ステップ)です。その中でも、同様の構成要素:沸騰の水は、カップを注ぎ、ゲストを与えました。これらの三つのステップは同じです。
変更点は以下のとおりです。赤のバブル紅茶やコーヒー、砂糖/ミルクまたはレモンこれらの2つの手順が変更されます。
プロジェクトの進化の最初のバージョン:
私たちは、共通のクラスに出て抽出変わります。HotDrink 。そして、コーヒーと紅茶が共通のクラスを継承してみましょう。次のように図のクラスを得:
hotdrinkスーパークラスのコードは次のとおりです。
プロジェクトの進化の第二のバージョン:
分析の後、我々は、2つのプロセスことがわかっただけでなく、同じ場所:
ステップ1 2つのプロセスが同じ(すべての5つのステップ)です。
2.醸造お茶やコーヒーが動作しているかどうか。
3.かどうかは、すべての砂糖やレモン調味料を追加します。
だから、一度私たちは、進行中のプロジェクトの抽出物:
我々はまた、2及び3の動作がスーパークラス内に配置され、動作フロースーパークラスを抽出します。サブクラスの実装をしてみましょう。従ってようにして得られたクラス図は、以下:
私たちは、このhotdrinkカテゴリ内で見てみましょう:
パブリック抽象クラス HotDrink {
公共最終ボイド prepareRecipe(){
お湯をわかす();
BREW();
pourInCup();
addCondiments();
送信();
}
保護された抽象無効 addCondiments();
protected abstract void brew();
private final void boilWater() {
System.out.println("一.烧水");
}
private final void pourInCup() {
System.out.println("三.倒入杯中");
}
我们发现,在prepareRecipe方法和boilWter、pourInCup、send这四个操作都添加了final关键字来修改。这是为什么呢?
从上面分析,我们知道,都是五个步骤,而且五个步骤中的三个步骤(烧水、倒入杯中、送客人)也是固定不变的。那么,在Java中,固定不变的这个怎么表示呢?对了,就使用fianl这个关键字修饰就可以了。这样,就可以放置子类不能随便修改步骤(比如由五步变成三步),已经规定的不能在修改了。比如烧水这个不烧了,这样是不行的。
我们来看看,热饮coffee和tea的类:
hotDrinkTea:
测试方法:
运行结果:
我们对项目进化进行复盘总结,可以得到:
所谓的模板模式:封装了一个算法的步骤,并允许子类为一个或多个步骤方法提供实现。模板模式,可以使子类在不改变算法结构(如上面的五步)的情况下,重新定义算法中某些步骤(如上面的第二步和第四步)
模板模式类图如下:
类图说明:
1:是一个抽象类(如:hotDrink)
2:有个模板方法。这个模板方法是final的(如:prepareRecipe方法)
3:由三种方法:
AbsOperation:抽象的方法(泡咖啡、加牛奶)
concreteOp:特定の方法(例えば、沸騰水する又は最終であってもなくてもよいです。)
フック:フック。親クラスをオーバーライドすることができ、サブクラスから選択することができます。
のは、下のフックで証明してみましょう。
例えば、今、顧客が選択したり、調味料を追加する必要があり、新たな需要を持っています。これは、どのようにそれを行うには?
この記事の出所:
凱歌のJava(kaigejava)
凱歌個人のブログ:www.kaigejava.com
私たちは再定義したテンプレート:
お茶はレモンで、このテンプレートクラスを実装し、そしてません。
テストの実行:
結果: