- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我知道这是一个常被践踏的领域,但我有一个具体问题……我保证。
在静态类型、面向对象的世界中花费的时间很少,我最近在阅读 Crafting Interpreters 时遇到了这种设计模式。 .虽然我理解这种模式允许在一组定义明确的现有类型(类)上实现可扩展的行为(方法),但我不太明白将其描述为双重分派(dispatch)问题的解决方案,至少不是没有一些额外的假设。我认为它更像是对 expression problem 的权衡。 ,您将封闭类型换成开放方法。
在我见过的大多数例子中,你最终会得到这样的东西(无耻地从很棒的 Clojure Design Patterns 中偷来的)
public interface Visitor {
void visit(Activity a);
void visit(Message m);
}
public class PDFVisitor implements Visitor {
@Override
public void visit(Activity a) {
PDFExporter.export(a);
}
@Override
public void visit(Message m) {
PDFExporter.export(m);
}
}
public abstract class Item {
abstract void accept(Visitor v);
}
class Message extends Item {
@Override
void accept(Visitor v) {
v.visit(this);
}
}
class Activity extends Item {
@Override
void accept(Visitor v) {
v.visit(this);
}
}
Item i = new Message();
Visitor v = new PDFVisitor();
i.accept(v);
这里我们有一组类型(Message 和 Activity),它们可能是关闭的或不经常更改的,以及一组我们希望对扩展开放的方法(访问者)。现在我感到困惑的是,在大多数示例中,它们将展示如何在不触及现有类的情况下实现其他访问者,例如像这样:
public class XMLVisitor implements Visitor {
@Override
public void visit(Activity a) {
XMLExporter.export(a);
}
@Override
public void visit(Message m) {
XMLExporter.export(m);
}
}
然后用手暗示这是“双重 dispatch ”,但事实并非如此。这里 accept
动态调度 Item
的子类型,但在 accept
中,visit
方法静态调度给传入的访问者通过方法重载。所以我们在 Item
上有一个单独的调度,然后 accept
中的“第二个”静态调度实际上是关于选择一个行为(方法)来调用那个 Item
类型。只有一种“类型”被分派(dispatch),而不是两种 - 第二种是一种行为。
当我想到双重分派(dispatch)时,我想到的是根据两个参数的类型进行分派(dispatch)的函数。一种行为,两种类型。
export(Activity,XML)
export(Activity,PDF)
export(Message,XML)
export(Message,PDF)
对我而言,这与访问者模式略有不同,访问者模式允许将任何行为集扩展到现有类,但这些行为不一定都代表与四个 export
中相同的行为上面的例子 - 它们可以是任何东西。如果我们添加另一个访客,它可能代表导出,但也可能不导出。从 API 层,您只需调用 accept
方法并相信传入的 Visitor 会执行您想要的操作,无论是什么。
我是不是看错了?
最佳答案
来自@user207421 的评论是正确的。如果一种语言本身不支持双重分派(dispatch),则没有任何设计模式可以改变该语言以使其支持。一种模式仅提供一种替代方案,它可以解决双重分派(dispatch)将应用于另一种语言的一些问题。
已经了解双重 dispatch 的学习访问者模式的人可能会得到解释的帮助,例如“访问者解决了与双重 dispatch 解决的问题类似的一组问题”。不幸的是,这种解释通常被简化为“访问者实现双重调度”,这是不正确的。
您已经认识到这一点意味着您已经对这两个概念有了扎实的理解。
关于java - 访客模式和双重 dispatch ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71229342/
对此感到疯狂,真的缺少一些东西。 我有webpack 4.6.0,webpack-cli ^ 2.1.2,所以是最新的。 在文档(https://webpack.js.org/concepts/mod
object Host "os.google.com" { import "windows" address = "linux.google.com" groups = ["linux"] } obj
每当我安装我的应用程序时,我都可以将数据库从 Assets 文件夹复制到 /data/data/packagename/databases/ .到此为止,应用程序工作得很好。 但 10 或 15 秒后
我在 cc 模式缓冲区中使用 hideshow.el 来折叠我不查看的文件部分。 如果能够在 XML 文档中做到这一点就好了。我使用 emacs 22.2.1 和内置的 sgml-mode 进行 xm
已结束。此问题不符合 Stack Overflow guidelines .它目前不接受答案。 我们不允许提出有关书籍、工具、软件库等方面的建议的问题。您可以编辑问题,以便用事实和引用来回答它。 关闭
根据java: public Scanner useDelimiter(String pattern) Sets this scanner's delimiting pattern to a patt
我读过一些关于 PRG 模式以及它如何防止用户重新提交表单的文章。比如this post有一张不错的图: 我能理解为什么在收到 2xx 后用户刷新页面时不会发生表单提交。但我仍然想知道: (1) 如果
看看下面的图片,您可能会清楚地看到这一点。 那么如何在带有其他一些 View 的简单屏幕中实现没有任何弹出/对话框/模式的微调器日期选择器? 我在整个网络上进行了谷歌搜索,但没有找到与之相关的任何合适
我不知道该怎么做,我一直遇到问题。 以下是代码: rows = int(input()) for i in range(1,rows): for j in range(1,i+1):
我想为重写创建一个正则表达式。 将所有请求重写为 index.php(不需要匹配),它不是以/api 开头,或者不是以('.html',或'.js'或'.css'或'.png'结束) 我的例子还是这样
MVC模式代表 Model-View-Controller(模型-视图-控制器) 模式 MVC模式用于应用程序的分层开发 Model(模型) - 模型代表一个存取数据的对象或 JAVA PO
我想为组织模式创建一个 RDF 模式世界。您可能知道,组织模式文档基于层次结构大纲,其中标题是主要的分组实体。 * March auxiliary :PROPERTIES: :HLEVEL: 1 :E
我正在编写一个可以从文件中读取 JSON 数据的软件。该文件包含“person”——一个值为对象数组的对象。我打算使用 JSON 模式验证库来验证内容,而不是自己编写代码。符合代表以下数据的 JSON
假设我有 4 张 table 人 公司 团体 和 账单 现在bills/persons和bills/companys和bills/groups之间是多对多的关系。 我看到了 4 种可能的 sql 模式
假设您有这样的文档: doc1: id:1 text: ... references: Journal1, 2013, pag 123 references: Journal2, 2014,
我有这个架构。它检查评论,目前工作正常。 var schema = { id: '', type: 'object', additionalProperties: false, pro
这可能很简单,但有人可以解释为什么以下模式匹配不明智吗?它说其他规则,例如1, 0, _ 永远不会匹配。 let matchTest(n : int) = let ran = new Rand
我有以下选择序列作为 XML 模式的一部分。理想情况下,我想要一个序列: 来自 my:namespace 的元素必须严格解析。 来自任何其他命名空间的元素,不包括 ##targetNamespace和
我希望编写一个 json 模式来涵盖这个(简化的)示例 { "errorMessage": "", "nbRunningQueries": 0, "isError": Fals
首先,我是 f# 的新手,所以也许答案很明显,但我没有看到。所以我有一些带有 id 和值的元组。我知道我正在寻找的 id,我想从我传入的三个元组中选择正确的元组。我打算用两个 match 语句来做到这
我是一名优秀的程序员,十分优秀!