回答

24

访问者,策略和模板模式都包含了算法的应用,最大的区别在于它们是如何被引发的以及它们是如何在实践中使用的。同样的用例,看看对象的构造,看看区别

当我们没有能力将函数作为第一类对象传递时,经常使用策略模式,它需要一个非常具体的参数list并且只有它的参数列表在其呼叫模式中,例如:

struct MyStrat{ 
    void operator()(const Foo &_input){ 
     _input.up(2); 
    } 
}; 

std::for_each(myFooList.begin(), myFooList.end(), MyStrat()); 

这是t母鸡适用于“Foo”类型的对象列表。我们实际上没有其他方式将它应用于任何其他对象。

另一方面,访问者模式用于我们想要将算法应用于可能不共享相同签名但不具有相同成员函数的一堆对象。我们说访问者模式,因为遍历树或“不相关”对象的另一集时,它经常被用来(在继承的意义无关。)

struct MyVisitor{ 
    void visit(const Foo &_input){ 
     _input.up(2); 
    } 
    void visit(const Bar &_input){ 
     _input.raiseUp(2); 
    } 
    void visit(const Baz &_input){ 
     _input.setUp(2); 
    } 
}; 

这里,这个想法是,我们希望“向上”的所有这些对象。它们都不共享相同的成员函数签名,但都在概念上相关。因此,我们可以“访问”这些类中的每一个,但期望算法执行相同类型的任务。

通过使用访客模式,我们避免了需要将每个类包装在代理模式中。因此,对于N个类,我们希望将此算法应用于我们不需要制作N个代理类。我们只需要将N个方法添加到访问者类中。

模板方法与访问者和策略模式完全不同。通过模板,你要做的是强制执行相同类型的算法,但在层次结构中的不同子类中。例如:

class Duck{ 
public: 
    int count() =0; 
    void makeNoise(int times) =0; 
    void quack(){ makeNoise(count()); }//the template pattern is here 
}; 

class Mallard : public Duck{ 
public: 
    int count(){ return 4; } 
    void makeNoise(cout << "quack" << endl; } 
}; 

class Daffy{ 
public: 
    int count(){ return 1; } 
    void makeNoise(cout << "Why I ought to..." << endl; } 
}; 

所以算法的结果在层次内变化。

+0

它现在更加清晰。谢谢! = D – 2010-12-13 18:35:59

1

共性:

  1. 策略,模板方法和游客:所有这三种模式都归类为行为模式。

差异:

  1. 模板方法使用继承和策略使用组合物
  2. 由基类实现的模板方法应该不能被重写。通过这种方式,算法的结构是由超类控制和细节在子类
  3. 战略封装的接口背后的算法,这为我们提供了在运行改变算法的能力来实现时间
  4. 访问者模式用于对一组类似的对象执行操作。在访问者模式的帮助下,我们可以将操作逻辑从对象移动到另一个类
  5. 如果操作的实现发生变化,我们只需更改访问者类而不是触及所有其他对象。

看一看Template methodStrategyVisitorSourcemaking文章更好的理解。

相关文章:

When should I use the Visitor Design Pattern?

Real World Example of the Strategy Pattern

Template design pattern in JDK, could not find a method defining set of methods to be executed in order