3

在 Java 中,函数对象是无状态对象的实例(通常是实现策略接口的单例),其方法对其他对象的状态进行操作。这些是 Java 等价的将函数指针作为参数传递给方法,就像在 C 等语言中所做的那样。

1.5 中引入的 Java 枚举规范使程序员能够通过将策略“接口”指定为枚举声明中的一系列抽象方法声明来复制函数对象模式,然后必须为每个枚举常量实现这些声明。

因此,如果想将特定于常量的行为与枚举常量相关联,至少有两种选择:

  • 您可以先Enum声明implement策略接口,然后将行为作为函数对象存储在最终enum实例字段中。然后,客户端代码可以通过enum字段访问器方法调用该行为。

  • 您可以在声明中将“策略”声明为一种或多种abstract方法Enumenum编译器会坚持为每个常量实现这些。然后,客户端代码可以通过直接通过enum常量调用方法来调用行为。

在我看来,函数对象方法需要更多资源。需要在堆上分配对象,对于大型枚举,这可能是几个对象。通过访问器调用的需求似乎需要较慢的执行速度,但是我猜想现代 JVM 实现将足够智能以内联方法调用,从而使两种模式之间的执行速度相似。

我目前使用函数对象来为我编写的 JDBC 数据库应用程序指定“动态”元数据。这些对象描述了数据库的某些特性,例如列和行不变量、用于创建与枚举类对应的数据模型对象的工厂、用于获取和改变数据模型对象数据的访问器以及其他类似的元数据。

这种方法确实需要大量的样板文件。很多样板。

虽然使用特定于常量的方法并不能保证消除样板,但这种方法应该更简洁易读……也许更有效。

我应该重构我的枚举设计以使用特定于常量的方法来代替函数对象吗?

4

1 回答 1

1

我应该重构我的枚举设计以使用特定于常量的方法来代替函数对象吗?

如果您关心enum方法调用的性能和额外的引用成本(最多 10 纳秒),那么您根本不应该在关键路径中使用数据库。数据库访问通常为 10,000,000 纳秒。即使是您已经拥有的查询的行访问也可以是 10,000 纳秒。Java Chronicle 被设计成超轻量级、少 GC、无锁、低系统调用、数据持久性,甚至可以在 100 到 500 纳秒的数量级内持久化和重新读取一些较大的业务对象。

简而言之,你必须弄清楚什么规模对你来说很重要,并首先开始优化最大的击球手。这意味着使用商业分析器分析您的应用程序,当分析器放弃并说您没有创建任何垃圾并且没有使用任何 CPU 或访问任何数据库时,您才应该开始担心取消引用和使用对象来保存的成本功能。

于 2013-08-02T05:29:28.890 回答