105

この質問を見ました: 「ユーティリティ」クラスが悪い場合、汎用コードをどこに配置すればよいですか?

そして、なぜユーティリティクラスは悪なのでしょうか?

数十クラスの深さのドメイン モデルがあるとします。インスタンスを xml 化できるようにする必要があります。親で toXml メソッドを作成しますか? MyDomainXmlUtility.toXml ヘルパー クラスを作成する必要がありますか? これは、ビジネス ニーズがドメイン モデル全体に​​及ぶ場合です。それは本当にインスタンス メソッドに属しているのでしょうか。アプリケーションの XML 機能に多数の補助メソッドがある場合はどうでしょうか?

4

14 に答える 14

140

ユーティリティクラスは必ずしも悪ではありませんが、優れたオブジェクト指向設計を構成する原則に違反する可能性があります。優れたオブジェクト指向設計では、ほとんどのクラスは単一のものとそのすべての属性および操作を表す必要があります。モノを操作している場合、そのメソッドはおそらくそのモノのメンバーである必要があります。

ただし、ユーティリティクラスを使用して、多数のメソッドをグループ化できる場合があります。たとえば、java.util.Collections任意のJavaコレクションで使用できる多数のユーティリティを提供するクラスがあります。これらは特定の種類のコレクションに固有のものではなく、任意のコレクションで使用できるアルゴリズムを実装します。

実際、あなたがする必要があるのは、あなたのデザインについて考え、メソッドを置くことが最も理にかなっている場所を決定することです。通常、これはクラス内の操作として行われます。ただし、実際にはユーティリティクラスとして使用される場合もあります。ただし、ユーティリティクラスを使用する場合は、ランダムなメソッドをそのクラスに投入するだけでなく、目的と機能ごとにメソッドを整理してください。

于 2010-07-27T01:01:07.853 に答える
65

一般的なコンセンサスは、ユーティリティ クラス自体は悪ではないということだと思います。慎重に使用する必要があります。

  • 一般的で再利用可能な静的ユーティリティ メソッドを設計します。それらがステートレスであることを確認してください。つまり、静的変数はありません。

  • ユーティリティ メソッドが多数ある場合は、開発者が簡単に見つけられるようにクラスに分割します。

  • ドメイン クラスの静的メソッドまたはインスタンス メソッドがより適切なソリューションである場合は、ユーティリティ クラスを使用しないでください。たとえば、抽象基本クラスまたはインスタンス化可能なヘルパー クラスのメソッドがより適切なソリューションになるかどうかを検討してください。

  • Java 8 以降では、ユーティリティ クラスよりもインターフェイスの「デフォルト メソッド」の方が適している場合があります。(使用する場合: Java 8+ インターフェイスのデフォルト メソッドと抽象メソッドの比較を参照してください。)


この質問を見る別の方法は、引用された質問で、「ユーティリティクラスが「悪」である場合」がストローマンの議論であることを観察することです。それは私のようなものです:

「豚が空を飛べるなら、傘を持っていくべき?」.

上記の質問で、私は実際に豚が空飛べると言っているわけではありませ

典型的な「xyz は悪である」という発言は、極端な視点を提示して考えさせることを意図した修辞的な装置です。それらが文字通りの事実の記述として意図されていることはめったにありません。


1 - そして、そのストローマンの質問を、屋外にいるときは常に傘を持っていくべきかどうかのアドバイスとして解釈すべきではありません.

于 2010-07-27T00:56:14.390 に答える
17

ユーティリティクラスは、それらをサポートするデータで責任をグループ化できないため、問題があります。

ただし、これらは非常に便利であり、永続的な構造として、またはより徹底的なリファクタリング中の踏み石として、常に構築しています。

クリーンコードの観点から、ユーティリティクラスは単一責任とオープンクローズ原則に違反します。それらには変更する理由がたくさんあり、設計上拡張できません。それらは実際には、リファクタリング中に中間のくだらないものとしてのみ存在する必要があります。

于 2010-07-27T00:59:09.807 に答える
10

悪になり始めると思います

1)大きくなりすぎます(この場合は、意味のあるカテゴリにグループ化するだけです)。
2)静的メソッドであってはならないメソッドが存在する

しかし、これらの条件が満たされない限り、非常に役立つと思います。

于 2010-07-27T01:02:54.687 に答える
7

経験則

この問題は、次の 2 つの観点から見ることができます。

  • 全体的な*Utilメソッドは、多くの場合、不適切なコード設計または怠惰な命名規則を示唆しています。
  • これは、再利用可能なクロスドメイン ステートレス機能のための正当な設計ソリューションです。ほとんどすべての一般的な問題には、既存の解決策があることに注意してください。

util例 1.クラス/モジュールの正しい使用法。外部ライブラリの例

ローンとクレジット カードを管理するアプリケーションを作成しているとします。これらのモジュールからのデータは、Web サービスを介してjson形式で公開されます。理論的には、手動でオブジェクトを にある文字列に変換できますがjson、それは車輪の再発明になります。正しい解決策は、Java オブジェクトを目的の形式に変換するために使用される外部ライブラリを両方のモジュールに含めることです。(例の画像ではgsonを示しています)

ここに画像の説明を入力


util例 2.クラス/モジュールの正しい使用法。util他のチーム メンバーに言い訳をせずに自分の文章を書く

ユースケースとして、アプリケーションの 2 つのモジュールでいくつかの計算を実行する必要があると仮定しますが、どちらもポーランドの祝日を知る必要があります。理論的には、これらの計算をモジュール内で行うことができますが、この機能を別のモジュールに抽出することをお勧めします。

これは小さいながらも重要な詳細です。あなたが書いたクラス/モジュールは ではなく と呼ばれHolidayUtilますPolishHolidayCalculator。機能的にはutilクラスですが、一般的な言葉を避けることができました。

ここに画像の説明を入力

于 2017-06-05T10:00:16.027 に答える
5

ユーティリティクラスは、クラスのより良い名前を考えるのが面倒だったことを意味するため、悪いです:)

そうは言っても、私は怠け者です。時々、仕事を終わらせる必要があるだけで頭が真っ白になることがあります..「ユーティリティ」クラスが忍び寄り始めるのはそのときです.

于 2010-07-27T01:41:19.477 に答える
3

ユーティリティ クラスが悪であることに完全に同意するわけではありません。

ユーティリティ クラスはいくつかの点でオブジェクト指向の原則に違反する場合がありますが、必ずしも悪いわけではありません。

たとえば、 value に一致するすべての部分文字列の文字列を消去する関数が必要だとしますx

STL C++ (現時点では) はこれを直接サポートしていません。

のポリモーフィック拡張を作成できますstd::string

しかし問題は、プロジェクトで使用するすべての文字列を拡張文字列クラスにしたいですか?

オブジェクト指向が本当に意味をなさない場合があり、これもその 1 つです。私たちのプログラムは他のプログラムと互換性があるようにしたいのでstd::string、クラスStringUtil_(または何か) に固執して作成します。

クラスごとに 1 つのユーティリティを使用するのが最善だと思います。すべてのクラスに 1 つのユーティリティを使用したり、1 つのクラスに多数のユーティリティを使用したりするのはばかげていると思います。

于 2016-06-09T13:15:10.947 に答える
2

デザイナーがコードを配置する適切な場所を考えることができなかったという理由だけで、ユーティリティをブランド化するのは非常に簡単です。多くの場合、真の「ユーティリティ」はほとんどありません。

経験則として、私は通常、コードを最初に使用されるパッケージに保持し、後で他の場所で本当に必要であることがわかった場合にのみ、より一般的な場所にリファクタリングします。唯一の例外は、同様の/関連する機能を実行するパッケージがすでにあり、コードがそこに最適である場合です。

于 2010-07-27T01:00:33.550 に答える
2

ステートレスな静的メソッドを含むユーティリティ クラスが役立つ場合があります。多くの場合、これらは単体テストが非常に簡単です。

于 2010-07-27T03:44:12.697 に答える
1

Java 8 では、インターフェイスで静的メソッドを使用できます...問題は解決しました。

于 2016-04-12T12:20:40.083 に答える
1

ほとんどの Util クラスは、次の理由で不適切です。

  1. それらはメソッドの範囲を広げます。彼らは、そうでなければ非公開になるコードを公開します。util メソッドが別々のクラスの複数の呼び出し元によって必要とされ、安定している (つまり、更新する必要がない) 場合は、プライベート ヘルパー メソッドをコピーして呼び出し元のクラスに貼り付ける方が良いと思います。APIとして公開すると、jarコンポーネントへのパブリックエントリポイントが何であるかを理解するのが難しくなります(メソッドごとに1つの親を持つ階層と呼ばれるツリー構造を維持します。これにより、精神的にコンポーネントに分離するのが簡単になります。複数の親メソッドから呼び出されたメソッドがあります)。
  2. それらはデッドコードになります。Util メソッドは、アプリが進化するにつれて使用されなくなり、使用されていないコードがコード ベースを汚染することになります。非公開のままだった場合、コンパイラはメソッドが使用されていないことを通知し、削除することができます (最良のコードはコードをまったく使用しないことです)。このようなメソッドを非プライベートにすると、コンピューターは無力になり、未使用のコードを削除できなくなります。これは、コンピューターが認識しているすべての別の jar ファイルから呼び出される可能性があります。

静的ライブラリと動的ライブラリにはいくつかの類似点があります。

于 2016-05-31T18:20:31.583 に答える
0

メソッドをクラスに追加できない場合 (たとえば、AccountJr. Developers による変更に対してロックされている場合)、次のように Utilities クラスにいくつかの静的メソッドを追加するだけです。

public static int method01_Account(Object o, String... args) {
    Account acc = (Account)o;
    ...
    return acc.getInt();
}  
于 2010-07-27T03:50:15.433 に答える