ユーティリティクラス(静的メソッドを持つクラス)とサービスクラス(「サービス」を提供するパブリックメソッドを持つクラス)のJavaの違いは何ですか。たとえば、暗号化オブジェクト(暗号化、復号化、ハッシュ、またはソルト値を取得するメソッドを提供する)はサービスプロバイダーであると主張できますが、多くの場合、この機能はCryptoUtil.encrypt(。。 。)。私はどちらがより良い「デザイン」に従うのかを理解しようとしています。考え?
5 に答える
さまざまなサービスオブジェクトを使用することで、さまざまな動作を実現できます。ユーティリティクラスの静的メソッドはスワップアウトできません。これは、テスト、実装の変更、およびその他の目的に非常に役立ちます。
たとえばCryptoUtil
、encrypt
メソッドでに言及します。さまざまな暗号化戦略、さまざまなメッセージ受信者などをサポートできるさまざまなオブジェクトがあると非常に便利です。
違いは、サービスクラスに状態がある場合があることです。そして状態とは会話状態を意味します。概念的な注文システムを考えてみましょう。
interface OrderSystem {
void login(String username, String password);
List<Item> search(String criteria);
void order(Item item);
void order(Item item, int quantity);
void update(Item item, int quantity);
void remove(Item item);
void checkout();
Map<Item, Integer> getCart();
void logout();
}
このようなことは、ステートフルセッションBean(1つの例として)を使用して実行できますが、その場合、認証はおそらく従来のEJBメカニズムでカバーされます。
ここでのポイントは、1つの呼び出しの結果が後続の呼び出しに影響を与えるという会話状態があるということです。静的メソッドは、ローカルで実行される一連の単純なステートレスサービスと見なすことができます。
サービスには、次のようなものを含むがこれらに限定されない、はるかに広い意味があります。
- ステートフル;
- リモート; と
- 実装に依存します(つまり、インターフェースを介して)。
私が思うベストプラクティスは、便利なメソッドとして静的メソッドを使用することです(特に、Javaには拡張メソッドがないため)。サービスはそれよりもはるかに豊富です。
静的メソッドをオーバーライドすることはできません。これは、2つの異なる方法でサービスを実装し、それらを切り替える場合に大きな問題になる可能性があります。このため、静的ユーティリティクラスの使用を、「決して」(「never」の値が十分に長い場合は:))複数の方法で実行する必要のない単純なものに制限します。
厳格なルールはないと思います。
私は通常、いくつかのパラメーターを必要とする機能に静的メソッドを使用し、単一のメソッド呼び出しで実行できます。例:
- 文字列のハッシュ値を計算する
- 日付を標準表現に変換する
機能に多くのパラメーターが必要であり、関連する結果がいくつか作成されている場合は、実際のアクションを実行するいくつかのメソッドを使用して、コンストラクターで共有パラメーターを受け入れることができるクラスを用意する方が実用的です。
典型的な例:最初に接続し、次にクエリを実行するために使用し、次に結果を取得するために使用するデータベース接続...
私は以前ここでこの質問に答えましたが、静的クラスを使用する場合、サービスの動作を変更すること(複数のサービスにリファクタリングすること)が非常に簡単であることがわかりました。
それが唯一の違いである場合(そして私はそれがそうだと信じています)、静的クラスを使用することは決して意味がありません。
誰かが「これらが1つ以上になることは決してないだろう」と言うときはいつでも、それらのn個をコーディングしてください。