访客设计模式 - 返回类型

Posted

技术标签:

【中文标题】访客设计模式 - 返回类型【英文标题】:Visitor Design Pattern - return type 【发布时间】:2015-04-12 18:36:50 【问题描述】:

我使用访问者设计模式来解决我们系统中的一个问题。作为参考如何实现它,我使用了DoFactory site 和This YouTube video。

在 DoFactory 示例中,Visitor 使用返回类型为“void”的方法,而在 YouTube 视频中,作者使用“double”。

我为什么要问: 在向公司 CTO 提出解决方案后,他接受了将其称为访客,但他声称如果访客不是 GoF 中所述的“无效”,而不是滥用真正的访客模式。

问题: 访客模式是否需要返回“void”? 我的意思是为了成为 DoFactory (GoF) 所描述的“真正的访问者模式”,或者它可以是任何返回类型并且仍然可以称为“真正的访问者模式”?

【问题讨论】:

很高兴知道other作者为什么选择返回double而不是什么都不返回(void);然后分析这些原因在这种情况下是否有效。大多数时候,谈论 pure 这种或那种模式会适得其反。只需以最适合您的方式使用它;不要太担心如何称呼它。如果您调用其中任何一个访问者模式,大多数人仍然会同意并理解您在说什么:首先,这是主要目标。让我们看看……定义“真实”。 我写了一个answer on Programmers.SE 涉及到这一点。简而言之,GoF 设计模式书确实包含返回任意对象的示例代码。这在很大程度上被忽视了,因为该代码在 Smalltalk 中,使用动态类型。 C++ 示例代码必须使用 void 是因为该语言的语义限制,而不是因为 void 返回类型是访问者模式的核心特征。在 Java 中,我们可以以类型安全的方式将泛型用于非 void 返回类型。 不允许 CTO 编码的另一个原因 :-) @Ostati 我认为这与 CTO 职位无关。 CTO 不应该自己编写代码可能是有原因的,但我认为这是对高级工程师之间的任何设计/审查讨论中可能出现的特定设计模式的轻微误解。 @Qw3ry 部分是开玩笑,部分是真的,部分是你想要的,但是是的,任何人都可以为所欲为,只要他们能够以正确的方式执行。 【参考方案1】:

设计模式旨在用作展示如何解决常见计算机科学问题的指南。欢迎您以任何您希望的方式偏离“真实”实现。

至于您的示例 youtube 视频,该视频的作者展示了如何使用访问者模式来计算不同类型物品的税费。每个visit 方法都返回双倍的金额,包括每件商品的税费。然后进行了不同的访问者实现,以展示如何在不更改代码的情况下使用不同的方法来计算税款(正常与免税期等)。

这个例子是一个“玩具”问题,旨在以一种易于理解的方式教授访问者模式的工作原理——它做得很好。

虽然我说欢迎您偏离 GoF 实现,但模仿此视频中的代码可能不是一个好主意。 视频中有一些内容在实际程序中使用是个坏主意。例如使用double 来赚钱。我认为双倍回报(为了钱)只是一种快速展示访问者工作方式的方式,您可能不应该使用它。

如果您想修改视频中的代码以返回 void。最简单的解决方案是在TaxVisitor 中有一个私有字段,用于累积总值并在每个访问方法中递增它。然后有一个 getter 来获得最终的总数。

作者还在他的访问者示例中明确调用了每个食物项目,这并没有展示访问者模式的强大功能。我会有一个可以访问的杂货项目的容器对象,并且它的接受方法将访问收据中的每个项目。

GroceryList groceries = new GroceryList();

groceries.add(new Milk(...));
groceries.add(new Liquor(...));
   ...


 TaxVisitor visitor = new TaxVisitor();

 visitor.accept(groceries);


 Money tax = visitor.getTax();

 Money preTaxTotal = groceries.getTotalPreTax();

 Money total = preTaxTotal.plus(tax);

//or compute tax during tax holiday
TaxVisitor holidayVisitor = new TaxHolidayVisitor();
  holidayVisitor.accept(groceries);


 Money holidayTax = holidayVisitor.getTax();

  Money holidayTotal = preTaxTotal.plus(holidayTax);

【讨论】:

以上是关于访客设计模式 - 返回类型的主要内容,如果未能解决你的问题,请参考以下文章

(嵌套?)多次调度 [访客模式]

javascript 访客行为设计模式

如何创建默认的“访客”会话,以便设计助手 current_user 显示我的访客用户?

带有内部树的访客设计模式

以访客至上的网页设计

快速结帐 PayPal,访客模式并不总是有效