15

我正在上课,我们刚刚了解了这些设计模式。但是我看不出它们之间有什么区别。它们听起来很像,在抽象类之上创建具体类。有人可以帮我消除这个疑问吗?谢谢 (:

4

2 回答 2

25

访问者、策略和模板模式都包含算法的应用。最大的区别在于它们是如何被唤起的,以及它们是如何在实践中使用的。虽然看起来它们具有相同的用例,但请查看对象的构造以了解差异。

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

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

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

然后将其应用于“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; }
};

所以算法的结果在层次结构中有所不同。

于 2010-11-24T12:38:48.523 回答
1

共同点:

  1. 策略、模板方法和访问者:所有三种模式都归类为行为模式。

差异:

  1. 模板方法使用继承,策略使用组合
  2. 基类实现的Template 方法不应被覆盖。这样,算法的结构由超类控制,细节在子类中实现
  3. Strategy将算法封装在一个接口后面,这为我们提供了在运行时更改算法的能力
  4. 访问者模式用于对一组相似类型的对象执行操作。借助访问者模式,我们可以将操作逻辑从对象移动到另一个类
  5. 如果 Operation 的实现发生了变化,我们只需要更改Visitor类而不是触及所有其他对象。

查看Template methodStrategyVisitorSourcemaking文章以获得更好的理解。

相关文章:

什么时候应该使用访问者设计模式?

策略模式的真实示例

JDK中的模板设计模式,找不到定义要按顺序执行的方法集的方法

于 2016-02-13T17:33:18.903 回答