策略,访问者和模板方法之间的区别是什么? [英] what's the difference between the patterns Strategy, Visitor and Template Method?

查看:173
本文介绍了策略,访问者和模板方法之间的区别是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在上课,我们刚刚了解了这些设计模式。但是我看不出有什么区别。他们听起来就像是一样的,在抽象的上面创造了具体的课程。有人可以帮我杀死这个疑问吗?感谢(:

解决方案

访客,策略和模板模式都包含算法的应用,最大的区别是在实践中他们是如何被引用的,以及它们在实践中如何使用,虽然看起来他们有相同的用例,但是看看对象的构造是否有所区别。



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

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

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

然后将其应用于类型Foo的对象列表。我们没有其他方法将其应用于任何其他对象。 / p>

v另一方面,当我们想将算法应用于可能不共享相同签名的一组对象,也不具有相同的成员函数时,使用isitor模式。我们说访问者模式,因为它经常在遍​​历树或另一个不相关对象的集合时使用(与继承意义无关)。

  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()); } //模板模式在这里
};

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

class Daffy {
public:
int count(){return 1;}
void makeNoise(cout<<为什么我应该...<< endl;}
};

所以算法的结果在父权制内有所不同。


I'm in a class where we just learned about these design patterns. However I couldn't see any difference between them. They sound just like the same, creating concrete classes over the abstract one. Could somebody help me kill this doubt? thanks (:

解决方案

Both the visitor, the strategy, and the template pattern encompass the application of an algorithm. The biggest difference is in how they are evoked and how they are used in practice. While it may seem like they have the same use case, look at the construction of the objects to see the difference.

The strategy pattern is often used when we don't have the ability to pass around functions as a first class object. It expects a very specific argument list and only that argument list in its call pattern. For instance:

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

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

which is then applied to a list of objects of type "Foo." We really have no other way of applying it to any other object.

The visitor pattern on the other hand is used when we want to apply an algorithm to a bunch of objects that might not share the same signature nor have the same member functions. We say visitor pattern because it's often used when traversing a tree or another collection of "unrelated" objects (unrelated in an inheritance sense.)

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 );
    }
 };

Here, the idea is that we'd like to "up" all these objects. They all don't share the same member function signature but all are conceptually related. Hence, we can "visit" each of these classes but expect the algorithm to perform the same type of task.

By using a visitor pattern we avoid the need to wrap each class in a proxy pattern. Hence, for N classes we'd like to apply this algorithm to we don't need to make N proxy classes. We only need to add N methods to a visitor class.

The template method is quite different from either the visitor and the strategy pattern. With the template what you're trying to do is enforce the same type of algorithm but on different subclasses within a hierarchy. For instance:

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; }
};

So the result of the algorithm varies within the heirarchy.

这篇关于策略,访问者和模板方法之间的区别是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆