论坛首页 Java企业应用论坛

Factory Method, Template Method, Strategy的比较

浏览 7349 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2006-10-12  
   先说Factory Method 和 Template Method,它们经常会一起被使用,原先对这两个模式的区别比较模糊:Factory Method 是一个抽象方法,具体实现在子类;而 Template Method 里也有些抽象方法,具体实现在子类;那他们之间什么区别?是由于看书不仔细,概念没理解。

  我们可以这样简单的认为:这些抽象的方法称之为 Factory Method,即定义在超类实现在子类的方法; Template Method 也是一个方法,它里面定义了一个算法逻辑,而这个算法逻辑可能要调用许多别的方法实现,这些‘别的方法’里就可能包含 Factory Method.
  例子:
public abstract class PizzaStore {
	/**
	 * #templateMethod(String type) is an Template Method.
	 * <p>
	 * #factoryMethodOfInit() AND #factoryMethodOfCreate(String type) are both
	 * Factory Method.
	 */
	public Pizza templateMethod(String type) {

		factoryMethodOfInit();
		Pizza pizza = factoryMethodOfCreate(type);

		System.out.println("--- Making a " + pizza.getName() + " ---");
		pizza.prepare();
		pizza.bake();
		pizza.cut();
		pizza.box();
		return pizza;
	}
	protected abstract void factoryMethodOfInit();
	protected abstract Pizza factoryMethodOfCreate(String type);
}


再对照看它们各自的定义,就更好理解了。
Factory Method:
   Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

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.

Template Method里所说的’lets subclasses redefine certain steps’就可以使用Factory Method.
在GOF书的Template Method 那章里是这样概述这两个模式之间关系的:
  Factory Methods are often called by template methods.

再就是Strategy Pattern,Spring Framework 里的DI就使用了这个模式。
修改了下上面的例子:
public abstract class PizzaStore {

	private PizzaCreator pizzaCreator;
	public Pizza templateMethod(String type) {
		factoryMethodOfInit();
		Pizza pizza = pizzaCreator.createPizza(type);
		System.out.println("--- Making a " + pizza.getName() + " ---");
		pizza.prepare();
		pizza.bake();
		pizza.cut();
		pizza.box();
		return pizza;
	}
	protected abstract void factoryMethodOfInit();
        public void setPizzaCreator(PizzaCreator pizzaCreator) {
		this.pizzaCreator = pizzaCreator;
	}
}


public interface PizzaCreator {
	public Pizza createPizza(String type);
}


public class londonPizzaCreator implements PizzaCreator {
	public Pizza createPizza(String type) {
		// TODO add creat detail
		return null;
	}
}


public class nYorkPizzaCreator implements PizzaCreator {
	public Pizza createPizza(String type) {
		// TODO add creat detail
		return null;
	}
}


PizzaCreator 接口定义了一个行为createPizza,具体实现类体现了不同的实现细节,比如londonPizzaCreator和nYorkPizzaCreator’生产’的Pizza肯定不一样。再通过给PizzaStore 设置(setPizzaCreator)不同的PizzaCreator 获得不同的Pizza(Pizza pizza = pizzaCreator.createPizza(type);)。
londonPizzaCreator和nYorkPizzaCreator就体现了Strategy Pattern,它们对createPizza有各自的实现算法,而使用时不需要知道其实现细节。它和Template Method的区别在于Strategy实现了算法逻辑,而Template Method只定义了算法的’框架’,而其中有些具体实现会涉及到子类。

Strategy:
  Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

Related to Template Method:
   Template methods use inheritance to vary part of an algorithm. Strategies use delegation to vary the entire algorithm.

// ------------------------------------------------------------
   一点学习体会,有不对的地方望大家指点。
   发表时间:2006-10-12  
偶现在只认INTERFACE和TDD,
至于里面是怎么实现的,虚还是不虚都无所谓了,
简单直接,将来易重构就好。
0 请登录后投票
   发表时间:2006-10-12  
Template的例子请看java.awt.Applet源码,Factory Method,故名思义,是创建新对象用的,你可以认为spring的BeanFactory就是Factory;Template Method是用回调来实现将某些共通的操作放在基类中……
0 请登录后投票
   发表时间:2006-10-12  
面向接口编程确实不错,有利于decouple,正在实践。
awt一直没怎么接触,Template Method 还是从Spring里看懂的。
还有其他些模式,也是接触Spring后更多的理解了。
:)
0 请登录后投票
   发表时间:2006-10-12  
GOF的模式,渐渐都快是反模式喽!
0 请登录后投票
   发表时间:2006-10-13  
galaxystar 写道
GOF的模式,渐渐都快是反模式喽!

此话怎讲的
0 请登录后投票
   发表时间:2006-10-24  
freizl 写道
galaxystar 写道
GOF的模式,渐渐都快是反模式喽!

此话怎讲的


胡讲乱讲。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics