zoukankan      html  css  js  c++  java
  • 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.

  • 相关阅读:
    如何把一个用户加入sodu组
    linux bond配置步骤,七种bond模式说明
    python 面向对象(进阶篇)
    lnmp搭建的常见错误
    Linux运维人员如何学习python编程
    运维日常工作知识总结
    《JS原型》
    《读王福朋有感》
    《使用Win32DiskImager安装Ubuntu16.04》
    因为无耻的查重系统,我删除了四篇随笔
  • 原文地址:https://www.cnblogs.com/shamgod/p/5260609.html
Copyright © 2011-2022 走看看