当“if else”/“instance of”不可避免时,除了使用访问者模式之外,我们如何改进设计?

2024-01-20

当我们有一个纯粹是语义继承而不是行为继承的对象层次结构时,我们不可避免地需要到处编写“instanceof”或“if/else”来进行运行时类型检查。

E.g.

如果我有一个对象层次结构

Class Function

Class Average extends Function

Class Sum extends Function

Class Max extends Function

如果这些类中有一个名为calculate()的方法,那么我们就没有问题,我们可以利用多态性,并且这种设计满足LSP。

但是,如果我们出于某种原因不想将此calculate()方法添加到此层次结构中,这些对象是纯粹的普通对象无状态对象,仅代表语义。

那么我们就被迫到处写下面的代码:

if (function instanceof Average)
//perform average
else if(function instanceof Sum)
//perform sum
else if(function instanceof Max)
//perform max

上面的代码表明了一个糟糕的设计,因为你到处都写这个代码,这个设计很脆弱,以后很难改变。我想如果函数的数量有限并且函数的计算在一个地方,这可能是可以的,具体取决于复杂性。

到目前为止我所知道的是,要解决上述方法,唯一可能的方法是实现访问者模式,除了使用访问者模式之外,还有其他方法可以解决上述设计吗?

我从访问者模式中看到的一个问题是访问者模式的accept方法没有返回值,如果accept()方法不能完全满足要求,有时这并不方便。


如果您在编译时仍然知道类型,则可以使用辅助类:

class Function {
}

class Average extends Function {
}

class Sum extends Function {
}

class Max extends Function {
}

class FunctionHelper {
  public Number calculate(Average a) {
    return null;
  }

  public Number calculate(Sum s) {
    return null;
  }

  public Number calculate(Max a) {
    return null;
  }

  public Number calculate(Function a) {
    return null;
  }

}

通常,您会将辅助方法设为静态,但您并不限于此 - 您可以使用多种风格的辅助类来执行一些相当有趣的操作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当“if else”/“instance of”不可避免时,除了使用访问者模式之外,我们如何改进设计? 的相关文章

  • 从脚本内更改自动热键托盘图标

    如何从 Autohotkey 脚本中将托盘图标更改为 my ico 例如 当脚本暂停时 为此 我在托盘菜单中提出了自己的 暂停脚本 菜单项 SingleInstance ignore Menu Tray Tip AutoCase 0 11
  • IE9-11 检测变换样式:preserve-3d

    我为一个项目制作了一个 3d 类型的菜单 自然 IE 会引起问题 因为 IE10 即使 3d 变换工作 也不支持变换样式 preserve 3d 我尝试了解决方法 通过对 3d 菜单容器的每个子元素应用变换 但至少可以说 动画看起来很糟糕
  • 文本溢出:省略号显示不同的字符

    我这里遇到了一些 CSS 问题 看这张图片 https www flickr com photos 125543025 N07 saved 1 在此图像中 我为文本 INTENSE TRAINING 添加了 CSS 样式 sample st
  • 使用 QtWebEngine 将 C++ 对象暴露给 Qt 中的 Javascript

    使用 QtWebkit 可以通过以下方式将 C 对象公开给 JavascriptQWebFrame addToJavaScriptWindowObject如中所述https stackoverflow com a 20685002 5959
  • Android Espresso 单击按钮时出现错误

    我正在尝试使用 espresso 框架为 Android 应用程序编写一些 UI 测试 现在我只是检查启动屏幕上是否存在所有元素 然后尝试单击登录按钮 单击按钮时 测试由于错误而失败 我似乎无法理解为什么会发生这种情况 我的测试代码是 Ru
  • Qt 布局,在小部件大小更改后调整到最小大小

    基本上我有一个QGridLayout里面有一些小部件 最重要的是 2 个标签 我用它们将图像绘制到屏幕上 好吧 如果用户愿意 他可以更改传入图像的分辨率 从而强制标签调整大小 我们假设标签的初始大小是320x240 用户将 VideoMod
  • bash:gitolite:找不到命令

    我正在尝试使用 Gitolite 在 Gitlab 中创建一个新分支 我完成安装步骤 当我遇到 设置 gitolite 部分时 我遇到了麻烦 我跟着这个link http sitaramc github com gitolite setup
  • ASP.NET Core MVC 视图组件搜索路径

    在此处的文档中 https learn microsoft com en us aspnet core mvc views view components view aspnetcore 2 2 https learn microsoft
  • xsi:type 属性搞乱了 C# XML 反序列化

    我使用 XSD exe 根据 XML 架构 xsd 文件 自动生成 C 对象 我正在反序列化 OpenCover 输出 但其中一个部分类未正确生成 这是导致异常的行
  • 一些基本的 PHP 问题 [已关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我只是有一些基本的 php 问题来加深我对学习的理解 但我找不到简单的答案 我有一个 php ajax 应用程序 它生成 mysql
  • Azure Functions 计时器触发器线程安全

    我想知道是否有人知道如果您在 Azure 函数上设置了 Cron 设置 如果其任务执行时间超过 5 分钟 则每 5 分钟运行一次 会发生什么情况 它备份吗 或者我应该实现一个锁定功能 以防止某些东西 例如在循环中 处理先前调用已经处理的数据
  • SimpleIoC - 在缓存中找不到类型:Windows.UI.Xaml.Controls.Frame

    第一次由 SimpleIoC 实例化我的 ViewModel 时 我遇到了以下错误 我相信我已经按应有的方式设置了容器 但由于某种原因 我仍然收到以下错误 任何想法或帮助将非常感激 Microsoft Practices ServiceLo
  • svn 强制迁移

    我正在考虑将我们的 svn 代码库迁移到 perforce 看看谷歌搜索结果 我确实找到了两个具有相同功能的工具 P4转换ftp ftp perforce com pub perforce tools p4convert docs inde
  • java'assert'和'if(){}else exit;'之间的区别

    java和java有什么区别assert and if else exit 我可以用吗if else exit代替assert 也许有点谷歌 您应该记住的主要事情是 if else 语句应该用于程序流程控制 而assert 关键字应该仅用于
  • R闪亮:使用闪亮的JS从数据表中获取信息

    我想读出所有列名称以及它们在数据表中显示的顺序 由于不同的原因 我无法使用 stateSave 等选项 我对 JS 没有什么把握 但我确信用它可以完成 所以我需要你帮助我 我尝试过类似的代码片段 datatable data callbac
  • React 错误:目标容器不是 DOM 元素

    我刚刚开始使用 React 所以这可能是一个非常简单的错误 但我们开始吧 我的html代码非常简单 load staticfiles
  • 从 JavaScript 中的 OnClientClick 事件中阻止 C# 中的 asp:Button OnClick 事件?

    我有一个asp Button在我的网页上 它调用 JavaScript 函数和代码隐藏方法 后者进行调用以导航到另一个页面 在 JavaScript 函数中 我正在检查条件 如果不满足这个条件 我想中止导航 以便OnClick方法未被调用
  • 自定义字符串查询操作的 Linq to NHibernate 可扩展性?

    我希望能够在 NHibernate Linq 表达式中使用自定义字符串查询 举例来说 这只是一个例子 我希望能够选择包含属性的实体 该属性是特定字符串的字谜 var myEntities EntityRepository AllEntiti
  • 计算包含字母/数字的行数

    我想要实现的目标很简单 但是解释起来有点困难 我不知道在 postgres 中这是否真的可能 我处于相当基础的水平 SELECT FROM WHERE LEFT JOIN ON HAVING 等等基本的东西 我正在尝试计算包含特定字母 数字
  • 如何使用 dql 从数据表中获取唯一值?

    我有一个表 其中有一列存储了各种值 我想使用 dql 从该表中检索唯一值 Doctrine Query create gt select rec school gt from Records rec gt where rec city ci

随机推荐

  • Scala Future 和 java 8 CompletableFuture

    的简介CompletableFuturesJava 8 带来了可用的语言功能scala concurrent Future例如一元变换 有什么区别 以及为什么 Scala 开发人员应该更喜欢 Scala Futures 而不是 java 8
  • 防止 Web 应用程序中同时发生事务

    我们有一个 Web 应用程序 它是一个游戏 其中包含许多不同的表单和元素 它们充当按钮并触发服务器上的一些操作 问题是 如果用户单击按钮太快或在两个选项卡中打开网站 然后同时发出一些操作 有时可能会混淆我们的应用程序 我们有一些基本的保护
  • 在 S3 存储桶之间移动文件的最佳方式?

    我想每天将一些文件从生产存储桶复制到开发存储桶 例如 复制 Productionbucket feed feedname date 到developmentbucket feed feedname date 由于我想要的文件在文件夹结构中太
  • 多个 RTSP 流不工作

    我在 Activity 中使用了 4 个 VideoView 如果 uri1 可用且其他 uri 不可用 则意味着所有视频视图都显示 uri1 的视频 如果其他 uri 可用但 uri1 未启动 则意味着所有视频视图均未显示任何内容 指导我
  • 打开 Chrome 或 Firefox,无需选项卡和其他菜单项,并设置屏幕位置和大小

    我需要在设定的位置启动 Chrome 或 Firefox 具有设定的大小 并且没有选项卡和其他菜单项 最终目标是一个桌面图标 我可以单击桌面图标以在桌面上的 x y 处获得一个 X 宽 Y 高的窗口 显示特定页面 而无需将这些设置永久保留在
  • vc++ 应用程序中的看门狗

    我写了一个简单的vc 后台应用程序 我正在尝试的就像一个看门狗服务 可以监视应用程序是否正在运行 如果应用程序崩溃 那么服务应该启动应用程序 为了通过 Windows 安装程序创建安装程序 我仅使用 app exe 和 app dll 是否
  • WPF - 绑定到菜单图标

    我有一个包含菜单的用户控件 我需要将 Menu Icon 绑定到 UserControl 的属性 但它不起作用 代码是这样开始的
  • 从可执行文件创建 Windows 服务

    是否有任何快速方法可以根据给定的可执行文件创建 Windows 服务 并在启动时启动它 要从可执行文件创建 Windows 服务 您可以使用sc exe sc exe create
  • Code OSS 和 Visual Studio Code 之间的差异

    正如开发商所说here https github com Microsoft vscode issues 60 issuecomment 161792005 所有这一切的最酷之处在于 您可以选择在我们的许可下使用 Visual Studio
  • 如何实现跨应用导航并导航回Fiori launchpad主页?

    在我们公司 我们建立了 Fiori 启动板 在其中 我们配置了一个链接到自定义开发的 SAPUI5 应用程序的磁贴 该应用程序作为 BSP 部署在服务器上 我们花了很长时间 但使用该应用程序中的路由器模式 我们成功地实现了从启动板磁贴到自定
  • 有没有脚本 SVG 编辑器?

    我想使用某种脚本语言 最好是 Python 编辑 SVG 文件 特别是 我想合并两个 SVG 文件 添加一些注释 并将它们排列在更大的图像中 有没有可用于此类目的的软件 Thanks Bartosz UPDATE 我最终决定使用nosklo
  • 网页字体大小中的px到底代表什么

    我正在做一些图形 在Javascript中 如果相关的话 我知道你可以使用pt px 等查找什么时px这意味着 每个网站似乎都有相同的模糊答案 字体大小 以像素为单位 我想知道什么exactly px代表 例如 如果我有20px 20 像素
  • 尝试与 Web 服务通信时遇到“没有到主机的路由”错误

    我正在尝试与我的笔记本电脑上的网络服务进行通信 并使用 Android 手机作为客户端 我试图做一个简单的登录功能 但是 每当客户端尝试与 Web 服务通信时 Eclipse 上的 DDMS 中就会弹出此错误 我可以通过家庭网络访问网络服务
  • Android 离线语音识别只显示一个结果?

    我已经设置了语音识别服务 如本文所示Android 语音识别作为 Android 4 1 和 4 2 上的服务 https stackoverflow com questions 14940657 android speech recogn
  • 如何使 Jinja2 中的 tojson() 过滤器输出 Unicode 而不是转义序列?

    我的模板是用于JS的 let SETTINGS settings tojson 4 我的设置是一个字典 name Russian name id 12345 如果我渲染它 我会得到 let SETTINGS name Russian nam
  • 使用用户变量访问结构成员

    假设我有一个结构如下 struct person int age char name 24 person 用户给出程序应该读取哪个结构成员的参数 program age int main int argc char argv int i i
  • 使用四边形的重心坐标

    你们中的一些人知道如何使用重心填充二维四边形 坐标 目前 我将四边形分成2个三角形 但这种方式效率低下 因为我必须迭代第二个 边界框重复先前填充的像素 通过 例如 为了填充第二个三角形 我遍历了第一个三角形 属于由第二个三角形形成的边界框
  • Lua 中的 OOP 和事件监听器 (Corona SDK)

    我在 Corona SDK 中的第一步和第一次遇到的麻烦 尝试制作两个盒子 我可以通过以下方式移动它们this http www ludicroussoftware com blog 2011 07 06 simple oop with i
  • 如何将图像列添加到 wicket 框架中的表中?

    我想在 wicket 框架中的表格的每个单元格中添加包含图像的列 我在 java 类中创建表格 并有一个 createColumns 方法 如下所示 private List
  • 当“if else”/“instance of”不可避免时,除了使用访问者模式之外,我们如何改进设计?

    当我们有一个纯粹是语义继承而不是行为继承的对象层次结构时 我们不可避免地需要到处编写 instanceof 或 if else 来进行运行时类型检查 E g 如果我有一个对象层次结构 Class Function Class Average