静的メソッドを介してオブジェクトを渡すことが有利なのはなぜですか?


9

オブジェクトでメソッドを呼び出すよりも、静的メソッドを使用してオブジェクトへの参照をパラメーターとして渡すほうが有利なのはなぜですか?

私の意味を明確にするために、次のクラスを検討してください。

public class SomeClass {
    private double someValue;

    public SomeClass() {
        // Some constructor in which someValue is set
    }

    public void incrementValue() {
        someValue++;
    }
}

静的メソッドを使用したこの代替実装と比較して:

public class SomeClass {
    private double someValue;

    public SomeClass() {
        // Some constructor in which someValue is set
    }

    public static void incrementValue(SomeClass obj) {
        obj.someValue++;
    }
}

私の質問はこのクラスだけに限定されていません。メソッドで呼び出すのではなく、オブジェクトを渡す任意のポイントが私が興味を持っているものです。これはこれまでに有利ですか?もしそうなら、なぜですか?


1
それは、2つのメソッドがまったく同じことをするコードのにおいのように感じます。静的メソッドが単に他のメソッドに委任された場合、それは役に立たないと感じますが、必ずしも「悪い」とは限りません
Nathan Merrill

13
@NathanMerrillポイントを逃していると思います。彼、最初の方法の代わりに 2番目の方法を作成して使用するほうが望ましい状況があるかどうかを尋ねています。

@Mego例で示したメソッドだけでなく、静的メソッドを使用してオブジェクトを渡す方が、オブジェクトのメソッドを呼び出すよりも良い瞬間があるどうか尋ねていますか?
Addison Crump

おそらくあなたは特にJavaを求めていますか?
エンダーランド2016年

3
この質問は、オブジェクト指向コードが何らかの最適なものであるという暗黙の仮定を立てていると思います。より手続き的または機能的なアプローチは、当然静的メソッドの使用につながります。...ただし、静的メソッドとインスタンスメソッドの間で機能を複製することは、かなりばかげています。私はそれが単なる例であり、あなたが話している実際のコードは静的なものだけであることを願っています。
jpmc26 2016年

回答:


34

自明な例:渡されたインスタンスが正当にnullになる可能性があり、これの(自明ではない)処理をメソッドに組み込みたい場合。


1
例:C#のString.Compare(Javaにも同様のものがあると思います)
edc65

Objects.equals()とObjects.compare()はJavaの例ですが、元のクラスにはありません。少なくともJavaの標準ライブラリでは、[オブジェクトの静的メソッドオブジェクトのようなものにインスタンスメソッドを持っているのが一般的だが、Sクラス。
ダボロス2016年

20

あなたの例では、インスタンスメソッドは明らかに勝者です。

一般的なケースでは、静的メソッドが適切ないくつかの理由を考えることができます。

  • ロジックをデータから分離することが理にかなっている状況があるため、静的メソッドを別のクラスに配置する必要があります(注:この例はその1つではありません)。

  • 2つ以上のオブジェクトを渡し、それらが同等に重要であることを強調したい。

  • null 有効な値です(ユーザー9000が説明)。


5

オブジェクトの状態を変更するメソッドを、静的メソッドではなくインスタンスメソッドとして含めることをお勧めします。

ただしpure、特定の検証ルールに基づいてオブジェクトをインスタンス化する必要がある場合など、メソッドであり、オブジェクトを入力として受け取る静的メソッドの例を見つけることができます。たとえば、.NETにDateTime.TryParse(String s, DateTime d)、オブジェクトを検証してインスタンス化するメソッドがあります。ただし、パラメーターDateTime dは明示的にとしてマークされoutます。

オブジェクトを比較して、比較結果のブール値や整数値ではなく、目的のオブジェクトを戻り値として取得したい場合もありますTeam.GetHigherScorer(teamA, teamB).IncreaseRanking()。これは以下よりもクリーンになります:

int compareResult = teamA.compareScoreWith(teamB);
if (compareResult == 1)
    teamA.IncreaseRanking();
else if (compareResult == -1) 
    teamB.IncreaseRanking();

(ケースを単純化するために「引き出し」のままにしておきます)。


1
「オブジェクト全体」を渡さない。参照をメモリ内の場所に渡します。これは、渡される非常に少量のデータです。パフォーマンスへの影響についてはわかりませんが、それでも... "out"マークは何を意味していますか?
Addison Crump 2016年

1
私は自分の発言から「全体」という言葉を落としましたが、混乱を招きました。私はパフォーマンスやサイズを意図していません。答えは純粋にプログラミングの実践に基づいています。とにかく、outある.Netパラメータの改質剤として使用するキーワード。これは、パラメーターが参照によって渡されることを示しています。詳細については、msdn.microsoft.com
en

4
最初の文は単に間違っています。そうすればclass C { int x; static void M() { 、Mは完全にアクセスできますx。たとえばint y = (new C()).x;合法です。
Eric Lippert 2016年

@EricLippert :)私はあなたが私が何を意味したか知っていると確信しています。マスターが行間を読む方法は驚くべきことです。その文章を編集する必要があるかもしれません。明確にするために、このようなこと static void M() { this.x = 1; }は不可能です。
ワンダーベル2016年

1
@wonderbell:いいえ、私はあなたが何を言っているのか知らなかったと確信しています。私はあなたが書いたものを知っていました。私はそれが注意this.xするので間違っていないx缶はアクセスできませんが、ためにthis存在していません。それはアクセスの問題ではなく、存在の問題です。
Eric Lippert 2016年

4

依存性注入は、静的メソッドの呼び出しを実行するための良い理由です。の具体的な実装にSomeClass継承チェーンがあるか、別のクラスの実装であると想定します。オブジェクトのモックを使用し、それをテスト目的で渡して、メソッドが想定どおりに動作することを確認し、そのステータスについて報告することができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.