HeadFirst设计模式之模板方法模式

模板方法模式详解:从咖啡到茶的制作流程
本文深入解析模板方法模式在不同场景的应用,通过具体案例(如制作咖啡和茶)来说明如何定义算法骨架并允许子类提供特定步骤的实现。文章还探讨了模板方法与好莱坞原则、排序算法以及JFrame、Applet中的hook方法之间的关系,展示了模式在实际编程中的灵活性和实用性。

一、

1.The Template Method defines the steps of an algorithm and allows subclasses to provide the implementation for one or more steps.

2.The Template Method Pattern defi nes the skeleton of an algorithm in a method, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.

3.With a hook, I can override the method, or not. It’s my choice.If I don’t, the abstract class provides a default implementation.

4.

二、

 

 

 

1.

 1 package headfirst.designpatterns.templatemethod.barista;
 2 
 3 public abstract class CaffeineBeverage {
 4   
 5     final void prepareRecipe() {
 6         boilWater();
 7         brew();
 8         pourInCup();
 9         addCondiments();
10     }
11  
12     abstract void brew();
13   
14     abstract void addCondiments();
15  
16     void boilWater() {
17         System.out.println("Boiling water");
18     }
19   
20     void pourInCup() {
21         System.out.println("Pouring into cup");
22     }
23 }

 

2.

 1 package headfirst.designpatterns.templatemethod.barista;
 2 
 3 public abstract class CaffeineBeverageWithHook {
 4  
 5     final void prepareRecipe() {
 6         boilWater();
 7         brew();
 8         pourInCup();
 9         if (customerWantsCondiments()) {
10             addCondiments();
11         }
12     }
13  
14     abstract void brew();
15  
16     abstract void addCondiments();
17  
18     void boilWater() {
19         System.out.println("Boiling water");
20     }
21  
22     void pourInCup() {
23         System.out.println("Pouring into cup");
24     }
25  
26     boolean customerWantsCondiments() {
27         return true;
28     }
29 }

 

3.

 1 package headfirst.designpatterns.templatemethod.barista;
 2 
 3 public class Coffee extends CaffeineBeverage {
 4     public void brew() {
 5         System.out.println("Dripping Coffee through filter");
 6     }
 7     public void addCondiments() {
 8         System.out.println("Adding Sugar and Milk");
 9     }
10 }

 

4.

 1 package headfirst.designpatterns.templatemethod.barista;
 2 
 3 import java.io.*;
 4 
 5 public class CoffeeWithHook extends CaffeineBeverageWithHook {
 6  
 7     public void brew() {
 8         System.out.println("Dripping Coffee through filter");
 9     }
10  
11     public void addCondiments() {
12         System.out.println("Adding Sugar and Milk");
13     }
14  
15     public boolean customerWantsCondiments() {
16 
17         String answer = getUserInput();
18 
19         if (answer.toLowerCase().startsWith("y")) {
20             return true;
21         } else {
22             return false;
23         }
24     }
25  
26     private String getUserInput() {
27         String answer = null;
28 
29         System.out.print("Would you like milk and sugar with your coffee (y/n)? ");
30 
31         BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
32         try {
33             answer = in.readLine();
34         } catch (IOException ioe) {
35             System.err.println("IO error trying to read your answer");
36         }
37         if (answer == null) {
38             return "no";
39         }
40         return answer;
41     }
42 }

 

5.

 1 package headfirst.designpatterns.templatemethod.barista;
 2 
 3 public class Tea extends CaffeineBeverage {
 4     public void brew() {
 5         System.out.println("Steeping the tea");
 6     }
 7     public void addCondiments() {
 8         System.out.println("Adding Lemon");
 9     }
10 }

 

6.

 1 package headfirst.designpatterns.templatemethod.barista;
 2 
 3 import java.io.*;
 4 
 5 public class TeaWithHook extends CaffeineBeverageWithHook {
 6  
 7     public void brew() {
 8         System.out.println("Steeping the tea");
 9     }
10  
11     public void addCondiments() {
12         System.out.println("Adding Lemon");
13     }
14  
15     public boolean customerWantsCondiments() {
16 
17         String answer = getUserInput();
18 
19         if (answer.toLowerCase().startsWith("y")) {
20             return true;
21         } else {
22             return false;
23         }
24     }
25  
26     private String getUserInput() {
27         // get the user's response
28         String answer = null;
29 
30         System.out.print("Would you like lemon with your tea (y/n)? ");
31 
32         BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
33         try {
34             answer = in.readLine();
35         } catch (IOException ioe) {
36             System.err.println("IO error trying to read your answer");
37         }
38         if (answer == null) {
39             return "no";
40         }
41         return answer;
42     }
43 }

 

7.

 1 package headfirst.designpatterns.templatemethod.barista;
 2 
 3 public class BeverageTestDrive {
 4     public static void main(String[] args) {
 5  
 6         Tea tea = new Tea();
 7         Coffee coffee = new Coffee();
 8  
 9         System.out.println("\nMaking tea...");
10         tea.prepareRecipe();
11  
12         System.out.println("\nMaking coffee...");
13         coffee.prepareRecipe();
14 
15  
16         TeaWithHook teaHook = new TeaWithHook();
17         CoffeeWithHook coffeeHook = new CoffeeWithHook();
18  
19         System.out.println("\nMaking tea...");
20         teaHook.prepareRecipe();
21  
22         System.out.println("\nMaking coffee...");
23         coffeeHook.prepareRecipe();
24     }
25 }

 

8.

 

三、The Hollywood Principle and Template Method

1.The Hollywood Principle Don’t call us, we’ll call you.

 

2.

3.

4.

5.

四、Sorting with Template Method

1.

 1 package headfirst.designpatterns.templatemethod.sort;
 2 
 3 public class Duck implements Comparable<Duck> {
 4     String name;
 5     int weight;
 6   
 7     public Duck(String name, int weight) {
 8         this.name = name;
 9         this.weight = weight;
10     }
11  
12     public String toString() {
13         return name + " weighs " + weight;
14     }
15   
16     public int compareTo(Duck object) {
17  
18         Duck otherDuck = object;
19   
20         if (this.weight < otherDuck.weight) {
21             return -1;
22         } else if (this.weight == otherDuck.weight) {
23             return 0;
24         } else { // this.weight > otherDuck.weight
25             return 1;
26         }
27     }
28 }

 

 

 

五、JFrame中的templateMethod的hook方法

1.If you haven’t encountered JFrame, it’s the most basic Swing container and inherits

a paint() method. By default, paint() does nothing because it’s a hook! By overriding
paint(), you can insert yourself into JFrame’s algorithm for displaying its area of the
screen and have your own graphic output incorporated into the JFrame. Here’s
an embarrassingly simple example of using a JFrame to override the paint() hook
method:

2.

 1 package headfirst.designpatterns.templatemethod.frame;
 2 
 3 import java.awt.*;
 4 import javax.swing.*;
 5 
 6 public class MyFrame extends JFrame {
 7     private static final long serialVersionUID = 2L;
 8 
 9     public MyFrame(String title) {
10         super(title);
11         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
12 
13         this.setSize(300,300);
14         this.setVisible(true);
15     }
16 
17 //    JFrame’s update algorithm calls paint(). By
18 //    default, paint() does nothing... it’s a hook.
19 //    We’re overriding paint(), and telling the
20 //    JFrame to draw a message in the window.
21     public void paint(Graphics graphics) {
22         super.paint(graphics);
23         String msg = "I rule!!";
24         graphics.drawString(msg, 100, 100);
25     }
26 
27     public static void main(String[] args) {
28         MyFrame myFrame = new MyFrame("Head First Design Patterns");
29     }
30 }

 

 

六、Applet的hook方法

1.Concrete applets make extensive use of hooks to supply their
own behaviors. Because these methods are implemented as
hooks, the applet isn’t required to implement them.

2.

 1 package headfirst.designpatterns.templatemethod.applet;
 2 
 3 import java.applet.Applet;
 4 import java.awt.Graphics;
 5 
 6 public class MyApplet extends Applet {
 7     private static final long serialVersionUID = 2L;
 8     String message;
 9  
10     public void init() {
11         message = "Hello World, I'm alive!";
12         repaint();
13     }
14  
15     public void start() {
16         message = "Now I'm starting up...";
17         repaint();
18     }
19  
20     public void stop() {
21         message = "Oh, now I'm being stopped...";
22         repaint();
23     }
24  
25     public void destroy() {
26         message = "Goodbye, cruel world";
27         repaint();
28     }
29  
30     public void paint(Graphics g) {
31         g.drawString(message, 5, 15);
32     }
33 }

 

 

 

3.


七、

1.

Q: When I’m creating a template method, how do I know when to use abstract methods and when to use hooks?
A: Use abstract methods when your subclass MUST provide an implementation of the method or step in the algorithm.
Use hooks when that part of the algorithm is optional. With hooks, a subclass may choose to implement that hook, but it doesn’t have to.

2.

Q: This implementation of sorting
actually seems more like the Strategy
Pattern than the Template Method
Pattern. Why do we consider it
Template Method?
A: You’re probably thinking that
because the Strategy Pattern uses object
composition. You’re right in a way – we’re 

using the Arrays object to sort our array, so
that’s similar to Strategy. But remember,
in Strategy, the class that you compose
with implements the entire algorithm. The
algorithm that Arrays implements for sort
is incomplete; it needs a class to fill in the
missing compareTo() method. So, in that
way, it’s more like Template Method.

 

3.

Q: Are there other examples of
template methods in the Java API?
A: Yes, you’ll find them in a few
places. For example, java.io has a read()
method in InputStream that subclasses
must implement and is used by the tempate
method read(byte b[], int off, int len).

 

4.

The Strategy and Template Method Patterns both encapsulate algorithms, one by inheritance and one by composition.

转载于:https://www.cnblogs.com/shamgod/p/5260609.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值