访客模式添加新功能

visitor pattern adding new functionality

我已阅读有关访问者模式的问题 https://softwareengineering.stackexchange.com/questions/132403/should-i-use-friend-classes-in-c-to-allow-access-to-hidden-members。在我读过的一个答案中

Visitor give you the ability to add functionality to a class without actually touching the class itself.

但是在访问的对象中我们必须添加新接口,所以我们实际上 "touch" class(或者至少在某些情况下放置 setter 和 getter,同时改变 class).

我将如何在不更改访问权限的情况下为访问者添加功能?class?

一旦为一个目的编写了访问者界面,您就可以通过不同的方式访问class。不同的访问不需要再次触摸 class ,假设您访问的是相同的组件。

访问者模式确实假定每个 class 接口都足够通用,因此,如果您知道对象的实际类型,就可以从 [=52] 外部执行操作=].如果这不是起点,访客确实可能不适用。

(请注意,此假设相对较弱 - 例如,如果每个数据成员都有一个 getter,那么对于任何 const 操作都可以轻松实现。)

这种模式的侧重点不同。如果

  1. 这是起点

  2. 您需要支持越来越多的操作

那么您需要对 class 的代码进行哪些更改才能将应用于指针(或引用)的新操作分派到基 class.

为了使这个更具体,取 classic visitor CAD example:

Consider the design of a 2D CAD system. At its core there are several types to represent basic geometric shapes like circles, lines and arcs. The entities are ordered into layers, and at the top of the type hierarchy is the drawing, which is simply a list of layers, plus some additional properties.

A fundamental operation on this type hierarchy is saving the drawing to the system's native file format. At first glance it may seem acceptable to add local save methods to all types in the hierarchy. But then we also want to be able to save drawings to other file formats, and adding more and more methods for saving into lots of different file formats soon clutters the relatively pure geometric data structure we started out with.

访问者模式的起点是,比方说,一个圆,有足够的 getters 来描述它的细节,例如它的半径。如果不是这样,那么确实存在问题(事实上,它可能是一个设计糟糕的 CAD 代码库)。

不过从这点出发,在考虑新的操作时,例如写入文件类型A,有两种方法:

  1. 为每个 class 和每个操作

    实现一个 virtual 方法,例如 write_to_file_type_a
  2. 只为每个class实现一个virtual方法accept_visitor,只有一次

您问题中的“没有实际接触 class 本身”意味着,在上面的第 2 点中,这就是将未来的访问者派遣到正确的 classes 所需的全部内容。这并不意味着访问者将开始写 getters,例如。