策略、访问者和模板方法模式之间有什么区别?

发布于 2024-10-04 03:46:40 字数 83 浏览 1 评论 0原文

我在课堂上刚刚学习了这些设计模式。但是我看不出它们之间有什么区别。它们听起来是一样的,都是在抽象类之上创建具体类。有人可以帮我打消这个疑虑吗?谢谢 (:

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 (:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

心碎的声音 2024-10-11 03:46:40

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

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

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

所以算法的结果在层次结构内是不同的。

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.

梦过后 2024-10-11 03:46:40

共性:

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

区别:

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

看看模板方法策略访客Sourcemaking 文章以便更好地理解。

相关文章:

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

策略模式的真实示例

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

Commonalities:

  1. Strategy, Template method and Visitor : All three patterns are categorized as behavioural patterns.

Differences:

  1. Template method uses Inheritance and Strategy uses composition
  2. The Template method implemented by the base class should not be overridden. In this way, the structure of the algorithm is controlled by the super class, and the details are implemented in the sub classes
  3. Strategy encapsulates the algorithm behind an interface, which provide us ability to change the algorithm at run time
  4. Visitor pattern is used to perform an operation on a group of similar kind of Objects. With the help of visitor pattern, we can move the operational logic from the objects to another class
  5. If there is a change in implementation of Operation, we have to just change Visitor class instead of touching all other objects.

Have a look at Template method , Strategy and Visitor and Sourcemaking articles for better understanding.

Related posts:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文