具有单一方法的类——最好的方法?

2023-11-24

假设我有一个旨在执行单个功能的类。执行完该功能后,就可以将其销毁。有什么理由选择其中一种方法吗?

// Initialize arguments in constructor
MyClass myObject = new MyClass(arg1, arg2, arg3);
myObject.myMethod();

// Pass arguments to method
MyClass myObject = new MyClass();
myObject.myMethod(arg1, arg2, arg3);

// Pass arguments to static method
MyClass.myMethod(arg1, arg2, arg3);

我故意对细节含糊其辞,试图获得针对不同情况的指导方针。但我并没有真正想到像 Math.random() 这样的简单库函数。我更多地考虑执行某些特定的复杂任务的类,但只需要一种(公共)方法来完成它。


我曾经喜欢充满静态方法的实用程序类。他们对辅助方法进行了很好的整合,否则这些方法会导致冗余和维护困难。它们非常易于使用,无需实例化,无需处置,只需即发即忘。我想这是我第一次无意中尝试创建面向服务的架构 - 许多无状态服务只完成其工作,仅此而已。然而,随着系统的发展,龙就会来临。

多态性
假设我们有一个方法 UtilityClass.SomeMethod 可以愉快地运行。突然我们需要稍微改变一下功能。大多数功能是相同的,但我们仍然必须更改一些部分。如果它不是静态方法,我们可以创建一个派生类并根据需要更改方法内容。因为它是静态方法,所以我们不能。当然,如果我们只需要在旧方法之前或之后添加功能,我们可以创建一个新类并在其中调用旧类 - 但这太恶心了。

接口问题
由于逻辑原因,静态方法不能通过接口定义。由于我们无法重写静态方法,因此当我们需要通过接口传递静态类时,静态类就没用了。这使得我们无法使用静态类作为策略模式的一部分。我们可能会通过以下方式修复一些问题传递委托而不是接口.

Testing
这基本上与上面提到的界面问题密切相关。由于我们交换实现的能力非常有限,因此我们在用测试代码替换生产代码时也会遇到麻烦。同样,我们可以将它们包装起来,但这需要我们更改大部分代码,以便能够接受包装器而不是实际的对象。

促进斑点
由于静态方法通常用作实用方法,而实用方法通常有不同的目的,因此我们很快就会得到一个充满非连贯功能的大类 - 理想情况下,每个类在系统中都应该有一个单一的目的。我宁愿有五倍的课程,只要它们的目的明确。

参数蠕变
首先,那个可爱又无辜的静态方法可能需要一个参数。随着功能的增长,添加了一些新参数。很快就会添加更多可选参数,因此我们创建该方法的重载(或者仅添加默认值,以支持它们的语言)。不久之后,我们就有了一个带有 10 个参数的方法。只有前三个是真正必需的,参数 4-7 是可选的。但是,如果指定了参数 6,则还需要填写 7-9...如果我们创建一个类,其唯一目的是执行此静态方法的操作,我们可以通过在构造函数,并允许用户通过属性或方法设置可选值,以同时设置多个相互依赖的值。另外,如果一个方法已经发展到如此复杂的程度,那么它很可能无论如何都需要位于自己的类中。

要求消费者无缘无故地创建类的实例
最常见的争论之一是,为什么要求我们类的使用者创建一个实例来调用这个单一方法,而之后却不再使用该实例?在大多数语言中创建类的实例是一个非常非常便宜的操作,因此速度不是问题。向消费者添加额外的代码行成本很低,可以为将来更易于维护的解决方案奠定基础。最后,如果您想避免创建实例,只需创建类的单例包装器即可轻松重用 - 尽管这确实要求您的类是无状态的。如果它不是无状态的,您仍然可以创建处理所有内容的静态包装方法,同时从长远来看仍然为您带来所有好处。最后,您还可以创建一个隐藏实例化的类,就好像它是单例一样:MyWrapper.Instance 是一个仅返回 new MyClass() 的属性;

只有西斯才能做到绝对
当然,我不喜欢静态方法也有例外。真正不会带来任何膨胀风险的实用程序类是静态方法的绝佳案例 - 例如 System.Convert。如果您的项目是一次性的,不需要将来维护,那么整体架构实际上并不是很重要 - 静态或非静态并不重要 - 但开发速度很重要。

标准、标准、标准!
使用实例方法并不妨碍您使用静态方法,反之亦然。只要差异化背后有理由,并且是标准化的。没有什么比查看包含不同实现方法的业务层更糟糕的了。

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

具有单一方法的类——最好的方法? 的相关文章

  • 获取 WPF 控件的所有附加事件处理程序

    我正在开发一个应用程序 在其中动态分配按钮的事件 现在的问题是 我希望获取按钮单击事件的所有事件 因为我希望删除以前的处理程序 我尝试将事件处理程序设置为 null 如下所示 Button Click null 但是我收到了一个无法分配 n
  • 关于在 Windows 上使用 WiFi Direct Api?

    我目前正在开发一个应用程序 我需要在其中创建链接 阅读 无线网络连接 在桌面应用程序 在 Windows 10 上 和平板电脑 Android 但无关紧要 之间 工作流程 按钮 gt 如果需要提升权限 gt 创建类似托管网络的 WiFi 网
  • 将 Excel 导入到 Datagridview

    我使用此代码打开 Excel 文件并将其保存在 DataGridView 中 string name Items string constr Provider Microsoft Jet OLEDB 4 0 Data Source Dial
  • java中日期转换dd-MMM-yyyy到dd-MM-yyyy

    在Java中将23 Mar 2011转换为23 03 2011的最简单方法是什么 感谢大家 这似乎解决了这个问题 try Calendar cal Calendar getInstance cal setTime new SimpleDat
  • C++:.bmp 到文件中的字节数组

    是的 我已经解决了与此相关的其他问题 但我发现它们没有太大帮助 他们提供了一些帮助 但我仍然有点困惑 所以这是我需要做的 我们有一个 132x65 的屏幕 我有一个 132x65 的 bmp 我想遍历 bmp 并将其分成小的 1x8 列以获
  • 获取包中声明的所有 Java 类的名称

    我正在编写一个功能 它将有助于将类放入我的程序的某个包中 另外 我只想要子类某个类的类 我需要这些类才能调用它们的静态方法 有没有一种自动的方法来做到这一点 如果是的话 速度慢吗 如果我不清楚 我想要的是这样的 ArrayList
  • Visual Studio 中的测试单独成功,但一组失败

    当我在 Visual Studio 中单独运行测试时 它们都顺利通过 然而 当我同时运行所有这些时 有些通过 有些失败 我尝试在每个测试方法之间暂停 1 秒 但没有成功 有任何想法吗 在此先感谢您的帮助 你们可能有一些共享数据 检查正在使用
  • 上下文敏感与歧义

    我对上下文敏感性和歧义如何相互影响感到困惑 我认为正确的是 歧义 歧义语法会导致使用左推导或右推导构建多个解析树 所有可能的语法都是二义性的语言是二义性语言 例如 C 是一种不明确的语言 因为 x y 总是可以表示两个不同的事物 如下所述
  • 如何在 Blackberry Cascades 中显示具有特定号码的电话板

    我正在使用带有 C QT 和 QML 的 Blackberry Cascades 10 Beta 3 SDK 以及 Blackberry 10 Dev Alpha Simulator 和 QNX Momentics IDE 并且我正在尝试实
  • 如何将自定义 JSON 文件添加到 IConfiguration 中?

    我正在使用 asp net Autofac 我正在尝试加载自定义 JSON 配置文件 并基于该文件创建 实例化 IConfiguration 实例 或者至少将我的文件包含到默认情况下构建的 IConfiguration asp net 中
  • 如何编写一个同时需要请求和响应Dtos的ServiceStack插件

    我需要提供本地化数据服务 所有本地化的响应 Dto 都共享相同的属性 IE 我定义了一个接口 ILocalizedDto 来标记那些 Dto 在请求端 有一个ILocalizedRequest对于需要本地化的请求 Using IPlugin
  • SimpleDateFormat 无法解析的日期 如果语言环境为 ES,则会出现错误。推特“创建时间”

    我正在尝试将 Twitter created at 转换为阿根廷日期时间 如果我这样做 final String TWITTER EEE MMM dd HH mm ss SimpleDateFormat sf new SimpleDateF
  • 更新分页。是否可以?

    他们是否存在一些方法来处理更新分页 例如我有 100 行类型 Id private Integer id Column private boolean flag Column private Date last 一开始它们看起来像 id f
  • 如何对 Web Api 操作进行后调用?

    我创建了一个 Web API 操作 如下所示 HttpPost public void Load string siteName string providerName UserDetails userDetails implementat
  • 如何在 Log4j2 - JSON 布局中自定义或删除默认属性

    In Spring Boot 2我已配置的应用程序Log4j2 with JsonLayout像下面这样
  • 如何在按钮单击时模拟按键 - Unity

    我对 Unity 中的脚本编写非常陌生 我正在尝试创建一个按钮 一旦单击它就需要模拟按下 F 键 要拾取一个项目 这是我当前的代码 在编写此代码之前我浏览了所有统一论坛 但找不到任何有效的东西 Code using System Colle
  • 英特尔 Pin 与 C++14

    问题 我有一些关于在 C 14 或其他 C 版本中使用英特尔 Pin 的问题 使用较新版本从较旧的 C 编译代码很少会出现任何问题 但由于 Intel Pin 是操作指令级别的 如果我使用 C 11 或 C 14 编译它 是否会出现任何不良
  • memset 未填充数组

    u32 iterations 5 u32 ecx u32 malloc sizeof u32 iterations memset ecx 0xBAADF00D sizeof u32 iterations printf 8X n ecx 0
  • 使用 GhostScript.NET 打印 PDF DPI 打印问题

    我在用GhostScript NET http ghostscriptnet codeplex com打印 PDF 当我以 96DPI 打印时 PDF 打印效果很好 但有点模糊 如果我尝试以 600DPI 打印文档 打印的页面会被极大地放大
  • 当另一个线程可能设置共享布尔标志(最多一次)时,是否可以读取共享布尔标志而不锁定它?

    我希望我的线程能够更优雅地关闭 因此我尝试实现一个简单的信号机制 我不认为我想要一个完全事件驱动的线程 所以我有一个工作人员有一种方法可以使用关键部分优雅地停止它Monitor 相当于C lock我相信 绘图线程 h class Drawi

随机推荐

  • 使用此关键字的 requestAnimationFrame

    我在用着webkitRequestAnimationFrame但我在对象内部使用它时遇到问题 如果我通过了this它将使用的关键字window我找不到它使用指定对象的方法 Example Display prototype draw fun
  • 让 Emacs fill-paragraph 能够很好地处理类似 javadoc 的注释

    我正在为我在工作中使用的 APL 方言编写 Emacs 主要模式 我已经得到了 基本字体锁定可以工作 并且在设置 comment start 和 注释 开始 跳过 注释 取消注释区域并填充段落 工作 然而 注释块通常包含 javadoc 风
  • 目前是否有无需身份验证即可获取 Instagram 用户媒体的方法?

    直到最近 还有多种无需 API 身份验证即可检索 Instagram 用户媒体的方法 但显然 该网站停止了所有这些 一些old方法 https api instagram com v1 users user id media recent
  • 有没有一种方法可以在不分配任何内存的情况下对数组进行排序?

    我需要非常频繁地对相当大的集合 数百 低数千个项目 进行排序 即每帧以 60 fps 进行排序 我使用的是 Unity 计算每个项目的密钥有点慢 因此需要缓存 我尝试过各种方法 List Sort 与 IComparer 每次都计算键 超级
  • 未命名命名空间内名称的外部链接

    根据C 标准第3 5 4条 未命名的命名空间或直接或间接声明的命名空间 在未命名的命名空间内具有内部链接 同时在第 7 3 1 1 段中我们有注释 96 尽管未命名命名空间中的实体可能具有外部链接 它们通过其翻译特有的名称进行有效限定 单元
  • 本地通知在 ios10 中不触发

    我在用着UNUserNotificationCenter对于 ios 10 为了进行测试 我将本地通知设置为从当前时间开始 10 秒 这就是我尝试过的 void viewDidLoad super viewDidLoad UNUserNot
  • HTML 将 WebGL Canvas 保存为图像

    我在用https github com auduno clmtrackr 我试图从以下示例中保存图像 https github com auduno clmtrackr blob dev examples facedeform html 问
  • 在客户端访问数据库就像在服务器端使用meteor一样

    我在文档中读到了这个 数据库无处不在 使用相同的透明 API 来访问您的 来自客户端或服务器的数据库 这很棒 但我认为存在一些安全问题 在客户端提供对数据库的完全透明的访问 您会遇到不良用户 他们会修改您的 JS 代码 实际上是在他的浏览器
  • svcutil.exe - 生成的代理不允许可空字段

    我试图通过使用 svcutil exe 创建 WCF 代理来使用使用 WSDL 指定的 Web 服务 但 WSDL 指定某些操作具有可选参数 minOccurs 0 例如
  • 从非托管 C++ 应用程序调用 C# dll,无需 COM

    有没有办法在不使用 COM 的情况下从 C 非托管应用程序调用 C DLL 您可以使用以下方法执行此操作Reverse P Invoke 示例和讨论here
  • ReSharper 6.1 是否可以与 Visual Studio 2012 配合使用?

    Resharper 6 1 支持 Visual Studio 2012 吗 我可以在 VS2010 上使用它 但想知道我是否需要升级到 ReSharper 7 0 以获得 VS2012 的支持 如果我这么做的话 我会很失望 捷脑公司承认虽然
  • bootstrap 3 到 bootstrap 4 列不再水平对齐[重复]

    这个问题在这里已经有答案了 我正在迁移到 bootstrap 4 但是我已将页面的 bootstrap min css 从 3 交换到 4 并且我的列现在全部垂直对齐 据我所知 列是正确的 我还使用 JS 小提琴进行测试 并且能够将它们全部
  • 对模板中的对象进行排序

    让这些模型 class Category models Model name models CharField max length 20 class Word models Model name models CharField max
  • R 使用 XML 数据时出现“externalptr”错误

    我正在 R 中处理一些 XML 数据 并遇到了有关 externalptr 类型的错误 1 当我尝试使用 xmlInternalTreeParse 函数 XML 包的一部分 时 出现以下错误 doc xmlInternalTreeParse
  • Magento:以编程方式添加新产品

    我正在尝试以编程方式将产品添加到 Magento 1 5 我的脚本最终将是一个 cron 作业 按照帐户系统提供的 XML 文件的指示定期更新和添加产品 我在创造新产品时遇到问题 我的脚本中的相关代码段是 attributeSetId 4
  • 将数组写入范围。只获取数组的第一个值

    我正在尝试将数组写入一个范围 并且尝试了多种方法 但无论如何 我总是一遍又一遍地只获得数组的第一个值 这是代码 Option Explicit Sub test ActiveWorkbook Worksheets Sheet1 Cells
  • 密集和稀疏矩阵的高效(时间和空间复杂度)数据结构

    我必须读取一个文件 其中存储了一个包含汽车的矩阵 1 蓝色汽车 2 红色汽车 0 空车 我需要编写一个算法来移动汽车矩阵的这种方式 蓝色的会动downward 红色的移动向右 有一个turn其中所有蓝色的都移动 然后轮流移动所有红色的 在读
  • Python:找到最小元素的最后一个索引?

    例如 1 2 3 4 1 2 具有最小元素 1 但它最后一次出现在索引 4 处 gt gt gt values 1 2 3 4 1 2 gt gt gt min x i for i x in enumerate values 1 4 无需修
  • 使用 OR 运算符检查变量值

    因此 我团队中的一位初级程序员今天编写了以下代码 if status incomplete unknown 这显然不会达到他的预期 即 if status incomplete status unknown 但我无法解释的是为什么第一段代码
  • 具有单一方法的类——最好的方法?

    假设我有一个旨在执行单个功能的类 执行完该功能后 就可以将其销毁 有什么理由选择其中一种方法吗 Initialize arguments in constructor MyClass myObject new MyClass arg1 ar