web-dev-qa-db-ja.com

静的メソッドのみを含む*** Helperまたは*** Utilクラスの使用はAntiPatternですか?

私はよくJavaまたは他の種類の言語でヘルパーまたはユーティリティクラスに直面しています。そのため、これが何らかのアンチパターンであり、これらの種類のクラスの存在が単なるソフトウェアの設計とアーキテクチャに欠落がないこと。

多くの場合、これらのクラスは、多くのことを行う静的メソッドだけを使用して制限されます。しかし、ほとんどの場合、実際にはコンテキストに依存し、ステートフルです。

私の質問は、そのような静的ヘルパー/ユーティリティクラスについてのあなたの意見は何ですか?利点はもちろんクラス名だけを使用した高速な呼び出しであるためです。

また、これらの種類のクラスの使用を避けたい抽象化レベルは何ですか?

私の意見では、「静的」というキーワードは、メソッド(Java)ではなく、クラス(Java)の宣言内でのみ許可されるべきです。私の意見では、このように使用することは、Procuedural-とOO-ParadigmsをJavaで組み合わせて、キーワードの誤用を避けることができるようにするための良い代替手段であり、途中である可能性があります。

回答による追加:

最初は、異なるパラダイムを組み合わせたり、マシンまたはvmコンパイル済みコード内でランタイム解釈スクリプト言語を使用したりできることは完全に合法だと思います。

私の経験では、プロジェクトの開発プロセス中に、そのような種類のヘルパーやユーティリティ、または名前が何であれ、成長し続け、コードベースの忘れられていた隅々で使用されていました。また、リファクタリングを行ったり、設計について再度検討したりする時間が足りないため、時間の経過とともに悪化するだけです。

staticはJavaから削除する必要があると思います。特に今では、さらに洗練された関数型言語要素を使用することが可能です。

20
Diversity

まあ、Javaには無料の関数がないため、静的関数としてプロ形式のクラスに配置する必要があります。必要な回避策は決して優雅さを欠いているかもしれませんが、アンチパターンではありません。 。

次に、無料の関数に問題はありません。実際には、無料の関数を使用すると、すべての厄介な詳細ではなくパブリックインターフェイスにしかアクセスできないため、結合が減少します。

もちろん、free/static関数を使用しても、可変グローバル、特にグローバルな状態の危険性は決して軽減されません。

20
Deduplicator

静的ユーティリティまたはヘルパー関数は、いくつかのガイドラインに準拠している場合、アンチパターンではありません。

  1. 彼らは副作用がないはずです

  2. これらは、これらの関数が動作するクラスに属さないアプリケーション固有の動作に使用されます

  3. 共有状態は必要ありません

一般的な使用例:

  • アプリケーション固有の方法で日付をフォーマットする
  • あるタイプを入力として受け取り、別のタイプを返す関数。

たとえば、私がユーザーに取り組んだアプリケーションでは、ユーザーの活動のために日誌エントリを保持しています。フォローアップ日を指定して、イベントのリマインダーをダウンロードできます。ジャーナルエントリを取得し、.icsファイルの生のテキストを返す静的ユーティリティクラスを作成しました。

状態を共有する必要はありませんでした。状態は変化せず、iCalイベントの作成はアプリケーション固有であり、ジャーナルエントリクラスに属していませんでした。

静的関数またはユーティリティクラスに副作用があるか、状態を共有する必要がある場合は、このコードを再評価することをお勧めします。これは、単体テスト用に模擬するのが難しいカップリングを導入するためです。

19
Greg Burghardt

それはあなたのアプローチに依存します。多くのアプリケーションは、古典的な考え方(使用しているサイトのスイートの多くを含む)とは対照的に、より機能的に書かれています。

この考え方では、静的メソッドとして連結できるワーカークラスにmanyユーティリティメソッドが存在します。それらは、データのみを保持し、渡されるプレーンオブジェクトに近い場所で供給/使用されます。

これは有効なアプローチであり、特に大規模な場合、非常にうまく機能します。

4
Tracker1

私は個人的に、そのようなヘルパークラスの唯一の重要な部分は、それらがプライベートにされることだと思います。それ以外に-それらは厳密に良いアイデアです(控えめに適用されます)。

これについて私が考える方法-クラス(または関数)を実装する場合-このようなものが役立ち、その実装をより明確にする場合、それはどのように悪いのでしょうか?そして、そのようなプライベートヘルパークラスを定義して、特定の形状のデータに依存する他のアルゴリズムとの統合および使用を可能にすることはOFTENにとって重要です。

「ヘルパー」というラベルを付けるかどうかは個人的な好みの小さな問題ですが、それは実装に役立ち、より広い聴衆に興味/使用のないことを暗示しています。それが理にかなっている場合-それのために行きます!

2
Lewis Pringle

誤解に基づくstaticヘルパークラスの普及。 staticメソッドのみを含むクラスを「ユーティリティクラス」と呼ぶからといって、POJOで共通の動作を記述できないことを意味するわけではありません。

staticヘルパークラスは、次の3つの理由からアンチパターンです。

  1. このヘルパーメソッドへの静的アクセスは、依存関係を隠します。これらの「ユーティリティクラス」がPOJOの場合、依存クラスをコンストラクタパラメータとして依存クラスに挿入すると、依存クラスのすべてのユーザーにとって依存関係が明確になります。

  2. このヘルパーメソッドへの静的アクセスは、密結合を引き起こします。これは、ヘルパーメソッドをusingするコードは再利用が難しく、(副作用として)テストするのが難しいことを意味します。

  3. 特にそれらがstateを維持している場合、これらは単にグローバル変数です。そして、うまくいけば、グローバル変数が良いことだと誰も主張しない...

静的ヘルパークラスは STUPIDコード アンチパターンの一部です。


グローバル状態は質問とは関係ありません– max630

OPは書きました:

しかし、ほとんどの場合、実際にはコンテキストに依存し、ステートフルです。

静的なステートフルコンストラクトはグローバルな状態です

あらゆる種類のコードで使用できます。 – max630

はい、原因の。そして、ほとんどすべてのアプリケーションは、ある種のグローバル状態を必要とします。

しかし、グローバル状態!=グローバル変数です。

グローバル状態はOOの手法で依存性注入を介して作成できますが、グローバル状態を回避することはできません下部にグローバル変数であるステートフルな静的構造を持ちます。

2
Timothy Truckle