3

Java では、関数オブジェクトはステートレス オブジェクト (通常は戦略インターフェイスを実装するシングルトン) のインスタンスであり、そのメソッドは他のオブジェクトの状態で動作します。これらは、C などの言語で行うように、メソッドへの引数として関数ポインターを渡すのと同等の Java です。

1.5 で導入された Java Enum 仕様により、プログラマーは、enum 宣言内の一連の抽象メソッド宣言として戦略「インターフェイス」を指定することにより、Function Object パターンを複製できます。これは、enum 定数ごとに実装する必要があります。

したがって、定数固有の動作を列挙型定数に関連付けるには、少なくとも 2 つの選択肢があります。

  • 最初に戦略インターフェイスをEnum宣言してから、動作を関数オブジェクトとして最終インスタンス フィールドに格納できます。その後、クライアント コードは、フィールド アクセサー メソッドを介して動作を呼び出すことができます。implementenumenum

  • 宣言で「戦略」を 1 つ以上のabstractメソッドとしてEnum宣言できます。enumコンパイラは、これらが各定数に対して実装されることを主張します。enumその後、クライアント コードは、定数を介してメソッドを直接呼び出すことにより、動作を呼び出すことができます。

関数オブジェクトのアプローチは、より多くのリソースを必要とするように私には思えます。オブジェクトはヒープに割り当てる必要があり、大きな列挙型の場合、これは数スコアのオブジェクトになる可能性があります。アクセサーを介して呼び出す必要があるため、実行が遅くなるように見えるかもしれませんが、最新の JVM 実装はメソッド呼び出しをインライン化するのに十分スマートであるため、2 つのパターン間で実行速度が似ていると思います。

私は現在、作成した JDBC データベース アプリの「動的」メタデータを指定する目的で関数オブジェクトを使用しています。これらのオブジェクトは、列と行の不変条件、enum クラスに対応するデータ モデル オブジェクトを作成するために使用するファクトリ、データ モデル オブジェクト データを取得および変更するためのアクセサ、およびその他の同様のメタデータなど、データベースの特定の機能を記述します。

このアプローチには、多くのボイラープレートが必要です。定型文がたくさん。

定数固有のメソッドを使用してもボイラープレートを排除できるとは限りませんが、このアプローチはより簡潔で読みやすく、おそらくより効率的であるはずです。

関数オブジェクトの代わりに定数固有のメソッドを使用するように列挙型の設計をリファクタリングする必要がありますか?

4

1 に答える 1

1

関数オブジェクトの代わりに定数固有のメソッドを使用するように列挙型の設計をリファクタリングする必要がありますか?

メソッド呼び出しのパフォーマンスenumと参照の追加コスト (最大 10 ナノ秒) を気にする場合は、クリティカル パスでデータベースを使用するべきではありません。データベースへのアクセスは通常、10,000,000 ナノ秒です。既に持っているクエリの行アクセスでさえ、10,000 ナノ秒になることがあります。Java Chronicle は、超軽量、GC レス、ロックレス、低システム コール、データ永続性を実現するように設計されており、100 から 500 ナノ秒のオーダーでより大きなビジネス オブジェクトを永続化して再読み取りします。

要するに、どの規模が自分にとって重要かを理解し、最初に最大の打者を最適化することから始めなければなりません。これは、商用プロファイラーを使用してアプリケーションをプロファイリングすることを意味し、プロファイラーがあきらめて、ガベージを作成していない、CPU を使用していない、またはデータベースにアクセスしていないと言った場合にのみ、オブジェクトを逆参照して保持するコストについて心配し始める必要があります。機能。

于 2013-08-02T05:29:28.890 に答える