行为型模式-模板方法模式(Template Method)

来源:互联网 发布:谷得网络这家公司怎样 编辑:程序博客网 时间:2024/05/16 07:00

一:定义:

Template Method:Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.

二:引入

一个咖啡店,卖咖啡和茶。

制作咖啡的步骤是:

  1. 把水煮开。
  2. 放入咖啡。
  3. 把煮好的咖啡倒进杯子。
  4. 加糖或奶。 

制作茶的步骤是:

  1. 把水煮开。
  2. 放入茶叶。
  3. 把茶倒进茶杯。
  4. 加柠檬或其他调料。
public class Coffee  {
    
public  void prepareRecipe()
    
{
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }

    
void boilWater()
    
{
        System.out.println(
"boil water");
    }

    
public void brew()
    
{
        System.out.println(
"brew coffee");
    }


    
void pourInCup()
    
{
        System.out.println(
"pour in cup");
    }

    
public void addCondiments()
    
{
        System.out.println(
"add sugar");
    }

}


public class Tea  {
    
public  void prepareRecipe()
    
{
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }

    
void boilWater()
    
{
        System.out.println(
"boil water");
    }

    
public void brew()
    
{
        System.out.println(
"brew tea");
    }

    
void pourInCup()
    
{
        System.out.println(
"pour in cup");
    }

    
public void addCondiments()
    
{
        System.out.println(
"add lemon");
    }

}

我们发现,制作两种饮料的方法有些地方是类似的,我们可以对这两个类进行抽象。

public abstract class CaffeineBeverage {
    
public final void prepareRecipe()
    
{
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }

    
void boilWater()
    
{
        System.out.println(
"boil water");
    }

    
    
void pourInCup()
    
{
        System.out.println(
"pour in cup");
    }

    
     
abstract void brew();
     
abstract void addCondiments();
}


public class Coffee extends CaffeineBeverage {
    
public void brew()
    
{
        System.out.println(
"brew coffee");
    }


    
public void addCondiments()
    
{
        System.out.println(
"add sugar");
    }

}


public class Client {
    
public static void main(String[] args) {
        CaffeineBeverage beverage
=new Coffee();
        beverage.prepareRecipe();

    }

}

父类提供了一个按步骤执行方法的模板,公共部分已经在父类实现,其它由具体子类自己实现。 

三:结构

    

四:实际应用

  1.   javx.servlet.http.HttpServlet

HttpServlet代码,doGet等方法由子类实现。

public abstract class HttpServlet
extends GenericServlet
implements Serializable
{

protected void service(HttpServletRequest request,HttpServletResponse response)
    
throws ServletException, IOException
  
{
    
if(request.getMethod().equals("GET") )
      
{
    
if(testConditional(request,response))
      doGet(request,response);
      }

    
else if (request.getMethod().equals("HEAD") )
      
{
    
if(testConditional(request,response))
      doHead(request,response);
      }

    
else if (request.getMethod().equals("POST") )
      
{
    doPost(request,response);
      }

    
else if (request.getMethod().equals("DELETE") )
      
{
    doDelete(request,response);
      }

    
else if (request.getMethod().equals("OPTIONS") )
      
{
    doOptions(request,response);
      }

    
else if (request.getMethod().equals("PUT") )
      
{
    doPut(request,response);
      }

    
else if (request.getMethod().equals("TRACE") )
      
{
    doTrace(request,response);
      }

    
else
      
{
    response.sendError(HttpServletResponse.SC_BAD_REQUEST,
"Method ""
               
+request.getMethod()+"" is not supported by this servlet");
      }

  }

  
   
protected void doGet(HttpServletRequest request,HttpServletResponse response)
    
throws ServletException, IOException
  
{
    response.sendError(HttpServletResponse.SC_BAD_REQUEST,
               
"Method "GET" is not supported by this servlet");
  }


 
}






  

一个例子:

public class HelloServlet extends HttpServlet {
   
public void doGet(HttpServletRequest request,
                  HttpServletResponse response)
     
throws ServletException, IOException
   
{
     response.setContentType(
"text/html");
     PrintWriter out 
= response.getWriter();
     out.println(
"Hello, World");
     out.close();
   }

 }

 

 五:适用情形

The Template Method pattern should be used

  • to implement the invariant parts of an algorithm once and leave it up to subclasses to implement the behavior that can vary.

     

  • when common behavior among subclasses should be factored and localized in a common class to avoid code duplication. This is a good example of "refactoring to generalize" as described by Opdyke and Johnson [OJ93]. You first identify the differences in the existing code and then separate the differences into new operations. Finally, you replace the differing code with a template method that calls one of these new operations.

     

  • to control subclasses extensions. You can define a template method that calls "hook" operations (see Consequences) at specific points, thereby permitting extensions only at those points.

参考文献:

1:阎宏,《Java与模式》,电子工业出版社
2:Eric Freeman & Elisabeth Freeman,《Head First Design Pattern》,O'REILLY
3:GOF,《designpatterns-elements.of.reuseable.object-oriented.software》 
原创粉丝点击