52

私は一般的に、一連の静的メソッドのみを含むヘルパー/ユーティリティ クラスにクラスから共通の動作を抽出していることに気づきます。これらのクラスをインスタンス化する正当な理由が本当に思いつかないので、これらのクラスを抽象として宣言する必要があるかどうか疑問に思うことがよくあります。

このようなクラスを抽象として宣言することの長所と短所は何でしょうか。

public [abstract] class Utilities{

   public static String getSomeData(){
       return "someData";
   }

   public static void doSomethingToObject(Object arg0){
   }
}
4

11 に答える 11

83

何もしないプライベート コンストラクターを宣言するだけです。

クラスを「abstract」と宣言する際の問題は、通常、abstract キーワードは、クラスがサブクラス化および拡張されることを意図していることを意味することです。それは間違いなくあなたがここで望んでいるものではありません.

于 2008-11-21T17:32:27.590 に答える
18

それらを抽象化する必要はありませんが、プライベートなパラメーターなしのコンストラクターを含めて、インスタンス化されないようにします。

興味のある人のための比較のポイント: C# では、クラスを静的であると宣言し、コンパイルされた形式でクラスを抽象化してシール (Java の最終) にし、インスタンス コンストラクターをまったく使用しません。また、その型のパラメーター、変数、配列などを宣言すると、コンパイル時エラーになります。ハンディ。

于 2008-11-21T17:33:14.127 に答える
12

ユーティリティ クラスを抽象宣言するのではなく、それらを final 宣言し、コンストラクターを非公開にします。そうすれば、サブクラス化することも、インスタンス化することもできません。



public final class Utility
{
    private Utility(){}

    public static void doSomethingUseful()
    {
        ...
    }
}
于 2008-11-22T17:51:38.130 に答える
4

プライベートコンストラクターを超えてさらにステップを追加します。

public class Foo {
   // non-instantiable class
   private Foo() { throw new AssertionError(); }
}

をスローするAssertionErrorと、同じクラスのメソッドがクラスをインスタンス化できなくなります (まあ、試行できます)。これは通常は問題になりませんが、チーム環境では、誰かが何をするかわかりません。

「abstract」キーワードに関しては、多数のインスタンスでサブクラス化されたユーティリティ クラスに気付きました。

public class CoreUtils { ... }
public class WebUtils extends CoreUtils { ... }

public class Foo { ... WebUtils.someMethodInCoreUtils() ... }

これは、ユーザーがどのユーティリティ クラスを含めるかを覚える必要がないようにするためだと思います。これには欠点がありますか?これはアンチパターンですか?

よろしく、LES

于 2009-01-29T20:35:27.093 に答える
3

それらを抽象として宣言することにより、これらのクラスの派生元を意図していることを他のコーダーに示すことになります。本当に、その通りです。大きな違いはありませんが、ここでのセマンティクスは、コードを見る他の人々の解釈に関するものです。

于 2008-11-21T17:31:55.580 に答える
2

他の人が述べたように、パラメーターのないプライベート コンストラクターを作成します。クラス自体を除いて、誰もそのインスタンスを作成できません。

他の言語でそれがどのように行われるかを他の人が示したように、次の C++ バージョンでどのように行うか、クラスをインスタンス化不可能にする方法を次に示します。

struct Utility { 
    static void doSomething() { /* ... */ } 
    Utility() = delete; 
};
于 2008-11-22T16:56:17.150 に答える
0

いいえ、しかし、あなたの言語がそれをサポートしている場合、ほとんどの場合、「静的」として宣言する必要がある(できる)という強力な議論があります...静的は、インスタンス化できないこと、およびそれらのすべてのメソッドをコンパイラに伝えます静的でなければなりません。

抽象は、派生クラスのインスタンスによって使用されるインスタンスベースの実装の詳細を持つクラス用です...

于 2008-11-21T17:31:57.890 に答える
0

ヘルパー/ユーティリティ メソッドは問題ありません。アプリケーションまたはフレームワーク内のライブラリにそれらを追加することについて心配する必要はありません。私が見たほとんどのフレームワークは、それらをさまざまな形で使用しています。

そうは言っても、それらについて本当に巧妙になりたい場合は、C# 3.0 の拡張メソッドを調べる必要があります。拡張メソッドを使用すると、ユーティリティがフレームワークの「全体論的」部分になり、抽象化することを検討して実行しようとしているように見えます。言うまでもなく、拡張メソッドは書くのがとても楽しいです!

于 2008-11-21T17:41:28.960 に答える
0

誰かが、C# 3.0 では拡張メソッドを介してこれを実現できると述べました。私は C# の専門家ではありません。1.5/2.0 の時代にいくつかやりましたが、それ以来使用していません。非常に大雑把な理解に基づいて、Javaで静的インポートを使用して同様のことを実現できると思います。まったく同じではないことはわかっていますが、これらのユーティリティメソッドを呼び出し元のクラスに対してもう少し「ネイティブ」に見せることだけが目的である場合(より適切な用語がないため)、それでうまくいくと思います。元の質問で宣言した Utilities クラスを想定しています。

import static Utilities.getSomeData;

public class Consumer {

    public void doSomething(){

        String data =  getSomeData();
    }

}
于 2008-11-22T16:14:53.020 に答える
0

建設的なアドバイスをいただけないでしょうか。

これを頻繁に行うと、2 つの問題に遭遇することになります。

まず第一に、パラメーターを取る静的メソッドは、多くの場合、そのパラメーターであるオブジェクトの一部である必要があります。これは String のようなオブジェクトには役に立たないことはわかっていますが、定義したオブジェクトを使用する場合は、ヘルパーをそのオブジェクトのメソッドとして含めることで、ほぼ確実にオブジェクトを改善できます。

すべてのネイティブ値を取る場合は、おそらくそれがメソッドであるオブジェクトを定義できます。これらのネイティブ値のグループ化を見つけて、オブジェクトとしてグループ化できるかどうかを確認してください。試してみると、その小さなミニオブジェクトの他の多くの用途が見つかり、気が付く前に驚くほど便利になります。

もう 1 つのことは、半関連の静的メソッドと静的変数の束を持つユーティリティ クラスがある場合、ほとんどの場合、それをシングルトンにしたいということです。私はこれを試行錯誤して見つけましたが、1つ以上が必要であることがわかった場合(最終的には必要になります)、シングルトンをマルチトン(?)に変更してから、静的クラスをマルチトン(わかりましたので、今言葉を作っています)。

幸運を。このようなことは、私にとってほとんど試行錯誤でした.5年前のように理解しましたが、静的クラス/メソッドを持たなかったことを後悔した例は見つかりませんでした.

于 2009-01-29T21:10:27.087 に答える