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


    一、

    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("
    Making tea...");
    10         tea.prepareRecipe();
    11  
    12         System.out.println("
    Making coffee...");
    13         coffee.prepareRecipe();
    14 
    15  
    16         TeaWithHook teaHook = new TeaWithHook();
    17         CoffeeWithHook coffeeHook = new CoffeeWithHook();
    18  
    19         System.out.println("
    Making tea...");
    20         teaHook.prepareRecipe();
    21  
    22         System.out.println("
    Making 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.

  • 相关阅读:
    P1182 数列分段`Section II`
    算法整理:Floyd_多源最短路
    【FBI WARNING】递归(高级数据结构的基础)
    【FBI WARNING】DP 从看透到看开
    两个例题
    结构体
    环状序列(Circular Sequence, ACM/ICPC Seoul 2004, UVa1584)
    生成元(Digit Generator, ACM/ICPC Seoul 2005, UVa1583)
    猜数字游戏的提示(Master-Mind Hints, UVa 340)
    回文词(Palindromes, UVa401)
  • 原文地址:https://www.cnblogs.com/shamgod/p/5260609.html
Copyright © 2020-2023  润新知