9

以下のクラス定義を前提としています。スタブメソッドを静的にするか非静的にするかをどのように決定しますか?

class Point {
    private final int x;
    private final int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    // Should the methods add(), subtract() and inverseOf() be non-static ...

    public Point add(Point point) {

    }

    public Point subtract(Point point) {

    }

    public Point inverseOf() {

    }


    // Or static?

    public static Point add(Point point1, Point point2) {

    }

    public static Point subtract(Point point1, Point point2) {

    }

    public static Point inverseOf(Point point) {

    }
}
4

11 に答える 11

9

私はインスタンスメソッドに行きます。次に、メソッドをインターフェイスの一部にして、それらをオーバーライドすることができます。2Dポイントまたは3Dポイントを処理する必要があり、実際には気にせず、インターフェイスを実装するポイントで操作を実行するだけでよいクライアントコードがある場合に、メリットが得られます。

于 2010-02-01T15:47:07.507 に答える
3

それはあなたが何を成し遂げようとしているのかによると思います。任意の2つのポイントを足し合わせるメソッドを提供する場合は、静的メソッドが必要です。ただし、特定のPointインスタンスにポイントを追加するメソッドが必要な場合は、非静的メソッドが必要です。

静的メソッドを使用する場合は、静的メソッドのみを含む別のユーティリティクラス(PointCalculator)に静的メソッドを配置することを検討できます。これはMathクラスに似ています。

于 2010-02-01T15:47:45.663 に答える
3

Pointたとえあなたが不変であっても、私はよりオブジェクト指向の非静的メソッドを選びます(そうです、あまりにも多くの静的メソッドを使用すると、ポリモーフィズム、継承などのオブジェクトの利点が失われます) 。そして実際には、これはクラスのようなBigDecimalまたはBigInteger設計された方法と一致します。その上、静的メソッドはクラスのテストを難しくするので、特に意味がある場合は、可能であればクラスの使用を避けたいと思います。

于 2010-02-01T15:56:10.103 に答える
2

意味的には、静的なアプローチはもう少し理にかなっているようです。もちろんどちらも機能しますが、非静的アプローチはあるポイントを別のポイントよりも優先し、さらに、呼び出しの結果としてpoint1(addが呼び出されるメソッド)が変更される可能性があることを意味します。

あなたのクラスを使用している開発者として、私が以下を見た場合:

Point p1 = new Point(1,2);
Point p2 = new Point(2,3);

p1.Add(p2);

また..

Point p1 = new Point(1,2);
Point p2 = new Point(2,3);

Point.Add(p1, p2);

私の自然な傾向は、非静的バージョンのadd()メソッドがpoint1を変更してpoint 2の結果を追加すると想定することです。静的アプローチを使用すると、メソッドが純粋であり、代表的なポイントは変更されていません。

于 2010-02-01T15:47:06.723 に答える
1

Javaを使用してオブジェクトを作成する場合は、スタイル的には、オブジェクトとデータのカプセル化を最大限に活用するようにしてください。私にとって、それはデータを(Pointクラスの)ある場所に残し、それを処理するために別のメソッドに渡さないことを意味します。オブジェクトを機能させます。ゲッターとセッターだけではありません。実際、ゲッターをまったく必要としないようにする方法については、よく考えてください。

不変クラスの新しいインスタンスを返す不変クラスにadd()やsubtract()のようなメソッドを使用することは完全に一般的です。これはFPのようなプログラミングに適したスタイルであり、このようなクラスには完全に合理的です。(良い例についてはBigIntegerまたはBigDecimalを参照してください。悪い壊れた恐ろしい例については日付またはカレンダーを参照しないでください。:)

クラスにメソッドを保持すると、オプションで、これらのクラスが実装する可能性のあるインターフェイスを定義したり、デコレータまたはアダプタパターンを使用したり、特定の種類のテストを記述したりできます。

于 2010-02-01T16:22:34.017 に答える
1

メソッドの本体が特定のインスタンスに依存しない場合は、静的メソッドを使用します。

一例として、あなたのadd(Point, Point)方法を見てください。Point関数に引数として渡される2つのを足し合わせて、別のを返しPointます。これは本当にいくつかへの内部this参照を必要としますかPoint

一方、メソッドがありますadd(Point)。おそらく、これはインスタンスに関数の引数を追加します-その場合、両方を持っているように、これをインスタンスメソッドにする必要がありますPoint

編集:私はもともと誤解したと思います。振り返ってみると、静的実装と非静的実装の両方に正しい署名があります。この時点では、両方が正しく機能することを知っているので、それはスタイルの問題だと思います。ポイントクラスをどのように使用しますか?Point a = Point.add(b, c)それがコードをより直感的に言うことができるかどうかを考えてくださいPoint a = b.add(c)。個人的には前者が好きです。どちらのオペランドも変更されないということです。

于 2010-02-01T15:23:34.283 に答える
0

当然、これらの関数は非静的でなければなりません。しかし、疑わしい場合はGRASPを参照してください、彼らはこのようなことを説明しています。

GRASP Information Expertによると、これらの関数は静的であってはなりません。

静的メソッドに関する直接的な情報がないという事実にもかかわらず、

情報専門家は、それを遂行するために必要な情報が最も多いクラスに責任を負わせるように私たちを導きます。

メソッドを静的にすると、ロジックが実際のデータからさらに移動し、データをメソッドに渡す必要があります。

staticを削除すると、ロジックが使用するデータに近くなります。

于 2010-02-01T15:25:00.847 に答える
0

私はこれに関する規範に反する傾向がありますが、どちらの方法も私には合理的であるように思われます。

  • これらのメソッドは、特にポイントを処理するため、明らかにポイントメソッドの一部である必要があります。
  • 2つのポイントを使用するメソッドの場合、一方のポイントについてもう一方のポイントよりも多くの情報が必要であることを意味するものは何もありません...したがって、メソッドが非静的メンバーになるインスタンスについてのプッシュはありません。

Javaのような言語の場合、特に上記の2番目のポイントのために、静的メソッドを使用します。演算子のオーバーロードがある言語(Rubyなど)の場合、それを利用するためにインスタンスメソッドを使用します。

于 2010-02-01T15:45:19.723 に答える
0

それらを静的にすると、ユニットテストも難しくなります。これを処理できる.NETで私が知っている唯一のモックフレームワークはTypeMockです。

このクラスを不変にすることが目的の場合は、アクセサで新しいPointオブジェクトを返すよりも、呼び出して、静的にすることはここではあまり意味がありません。

于 2010-03-18T19:50:05.877 に答える
-1

これらのメソッドは静的である必要があります。これは、クラス自体がコンストラクターを介して作成され、xとyがfinalであるために値が割り当てられるためです。つまり、ポイントを作成することはできますが、今後はデータを操作することはできません。Add / Extract / Etcメソッドはユーティリティメソッドであり、Pointのインスタンスを使用する必要はありません。

于 2010-02-01T15:56:38.997 に答える
-2

あなたの場合、署名をに変更しない限り、静的でない必要がありますpublic static Point add(Point point1, Point point2)

編集:私は投票されました。それはいいです。私は静的な方法を前に置くような些細な提案をしようとしていませんでした。この場合、インスタンスメソッドの方が優れていますが、実際には単一の答えはありません。それはあなたの好みに依存します。

于 2010-02-01T15:29:36.010 に答える