Java では、関数オブジェクトはステートレス オブジェクト (通常は戦略インターフェイスを実装するシングルトン) のインスタンスであり、そのメソッドは他のオブジェクトの状態で動作します。これらは、C などの言語で行うように、メソッドへの引数として関数ポインターを渡すのと同等の Java です。
1.5 で導入された Java Enum 仕様により、プログラマーは、enum 宣言内の一連の抽象メソッド宣言として戦略「インターフェイス」を指定することにより、Function Object パターンを複製できます。これは、enum 定数ごとに実装する必要があります。
したがって、定数固有の動作を列挙型定数に関連付けるには、少なくとも 2 つの選択肢があります。
最初に戦略インターフェイスを
Enum
宣言してから、動作を関数オブジェクトとして最終インスタンス フィールドに格納できます。その後、クライアント コードは、フィールド アクセサー メソッドを介して動作を呼び出すことができます。implement
enum
enum
宣言で「戦略」を 1 つ以上の
abstract
メソッドとしてEnum
宣言できます。enum
コンパイラは、これらが各定数に対して実装されることを主張します。enum
その後、クライアント コードは、定数を介してメソッドを直接呼び出すことにより、動作を呼び出すことができます。
関数オブジェクトのアプローチは、より多くのリソースを必要とするように私には思えます。オブジェクトはヒープに割り当てる必要があり、大きな列挙型の場合、これは数スコアのオブジェクトになる可能性があります。アクセサーを介して呼び出す必要があるため、実行が遅くなるように見えるかもしれませんが、最新の JVM 実装はメソッド呼び出しをインライン化するのに十分スマートであるため、2 つのパターン間で実行速度が似ていると思います。
私は現在、作成した JDBC データベース アプリの「動的」メタデータを指定する目的で関数オブジェクトを使用しています。これらのオブジェクトは、列と行の不変条件、enum クラスに対応するデータ モデル オブジェクトを作成するために使用するファクトリ、データ モデル オブジェクト データを取得および変更するためのアクセサ、およびその他の同様のメタデータなど、データベースの特定の機能を記述します。
このアプローチには、多くのボイラープレートが必要です。定型文がたくさん。
定数固有のメソッドを使用してもボイラープレートを排除できるとは限りませんが、このアプローチはより簡潔で読みやすく、おそらくより効率的であるはずです。
関数オブジェクトの代わりに定数固有のメソッドを使用するように列挙型の設計をリファクタリングする必要がありますか?