web-dev-qa-db-ja.com

メソッドを別のメソッドに再利用することが適切なのはいつですか?

私は、単一の管理会社の土地のさまざまな特性を説明するプログラムを書いています。このプログラムには、3つのオーバーロードされたaddPropertyメソッドがあります。私の質問は、他の2つのaddPropertyメソッド内でより一般的なaddProperty(Property p)メソッドを再利用できることです。

public int addProperty(Property p) {
    // From Assignment: Return -1(the property is null),
    // -2(array is full),
    // -3(plot for property !encompassed by MGMCP plot),
    // -4(if plot overlaps any other property plot)

    if(p == null)//what if p's Plot is 0?
        return -1;
    if(properties.length == MAX_PROPERTY)
        return -2;
    if(!plot.encompasses(p.getPlot()))
        return -3;
    if(overlapsExsistingProperties(p.getPlot()))
        return -4;

    properties[currentPropertyIndex] = new Property(p);

    return currentPropertyIndex++;
}// addProperty

public int addProperty(String name, String city, double rent, String owner) {
    return addProperty(new Property(name,city,rent,owner));
}// addProperty

public int addProperty(String name, String city, double rent, String owner, int x, int y, int width, int depth) {
    return addProperty(new Property(name,city,rent,owner,x,y,width,depth));
}// addProperty overload

上記のコードは良い習慣と見なされていますか?私は主に、他の内で最初のaddPropertyメソッドを呼び出すために2つのオブジェクト初期化がどのように必要かを検討しています。一方、各addPropertyのメソッド本体を書き直した場合、必要なオブジェクト初期化は1つだけです。

これはかなり基本的な例ですが、より大きなアプリケーションでは、パフォーマンスに影響を与えたり、ガベージコレクションの速度を低下させたりするでしょうか。

2
Alec Felix

異なる数のパラメーターを持つオーバーロードを持つことは一般的な方法です(パラメーターが少ないオーバーロードは、共通のデフォルトを使用して、パラメーターが多いオーバーロードを呼び出します)。または別の種類のパラメーター(ストリームやファイルパスなど)でも、あなたのやり方は少し奇妙です。 2番目と3番目の方法はほとんど役に立たず、混乱を招く可能性があります。クライアントコードは、そのオブジェクト自体を作成するのと同じくらい簡単に、最初のメソッドに渡すことができます。

あなたが言及している追加のインスタンス化は表示されません。ただし、単なるデータコンテナーである単純なオブジェクトを作成することは、それほど費用がかかることも心配することもありません(緊密なループにないと仮定します)。

2
Martin Maat

単に割り当てるのではなく、なぜPropertyオブジェクトを複製するのか、はっきりしません。

とにかく、具象クラスのインスタンス化は、「add」メソッド内では行わないでください。

オブジェクトの作成は、addProperty(Property p)で実行しているチェックを実行し、必須項目が欠落している場合に適切な例外をスローするファクトリー/作成者/ビルダークラスまたはメソッドで行う必要があります。

Addメソッドは、具体的な実装と密接に結びついてはなりません。渡されたパラメーターは抽象/インターフェースである必要があり、ファクトリー/ビルダーのみがnew予約語を​​介して具象クラスに密結合されます。

0

要するに

この一般的な方法は、パフォーマンスにほとんど影響を与えません。ただし、2つのクラス間を不必要に結合します。このアプローチの使用は、余分な利便性が結合の欠点を実際に上回る場合に限定してください。

もっと詳しく

設計制約がここでの本当の問題です:

  • addProperty()- overloadsのインターフェースは、Propertyのコンストラクターのインターフェースと強く結び付いています。
  • これは 単一の責任の原則 に違反します。つまり、クラスには変更する理由が1つだけあるはずです。ここでPlotLandクラスを変更する理由は2つあります。1つは独自のコア要件で、もう1つはPropertyのインターフェイスです。
  • その結果、ある日、構築時にPropertyの構築に別の属性を必須にする場合、インターフェイスを変更する必要があります。これにより、インターフェイスが使用されているすべての場所に変更が反映される可能性があります。 dオーバーロードが使用されるすべてのコードを変更する必要があります。
  • これは、適切な 懸念の分離 を目的とする 最小の知識の原則 にも反します。

このプラクティスのパフォーマンスへの影響は、一般に無視できます。

  • すべての場合において、その構築に必要なすべてのパラメータに基づいてプロパティを作成する必要があります。
  • オーバーロードでは、これらのパラメーターをもう一度渡し、「再利用」の追加の呼び出しを行います。しかし、組み込み型はコンパクトであり、クラスインスタンスはJavaで参照によって渡されるため、余分な労力は確かにナノ秒の問題にすぎません。
  • それは、FPSレートを低下させるリスクのあるコアゲームループにあると思いますが、私は慎重にベンチマークを作成すると言います。しかし、ビジネスアプリケーションでは、データベースにデータを格納する必要がある時間と比較して、この余分な労力は何もありません。

しかし、原則は私たちを導くためのものであり、私たちを命令するためのものではありません。したがって、最終的には、追加の利便性が追加の制約を上回るかどうかを決定するのはあなた次第です。

0
Christophe

私の質問は、他の2つのaddPropertyメソッド内でより一般的なaddProperty(Property p)メソッドを再利用できることです。

一般的に、はい。あるメソッドが別のメソッドを効果的にラップすることに本質的に問題はありません(オーバーロードかどうかに関係なく)。オーバーロードされたメソッド本体のかなりの部分が他の方法で繰り返される場合、これを行うことは実際にはT =のDRY原則に従います。

ただし、この場合、2番目と3番目のメソッドは、Propertyコンストラクターのラッパーにすぎないため、存在してはなりません。これはDRYに違反します。Propertyコンストラクターが変更された場合、「このメソッドを作成したため」以外の明らかな理由がない限り、このメソッドも変更する必要があります。

これらのメソッドのいずれかを呼び出す人(つまり、コンシューマー)はPropertyコンストラクターにアクセスできます。これは、必要なパラメーターをすでに把握していることを意味します。 2番目と3番目の方法は、同じ情報を繰り返すだけです。値は何も追加されませんが、Propertyコンストラクターが変更された場合にWETスポットになります。

私は主に、他の内で最初のaddPropertyメソッドを呼び出すのに2つのオブジェクト初期化がどのように必要かを検討しています。

コンシューマーが最初のメソッドを呼び出しても、2つの初期化を実行しています。

  1. addProperty(Property p)メソッドパラメータに渡されるオブジェクト
  2. このメソッド内でインスタンス化するnew Property(p)

あなたの懸念は有効かもしれませんが、3つの方法すべてで同じであるため、ここでの特定の質問には関係ありません。

なぜそうするのかよくわかりません

properties[currentPropertyIndex] = new Property(p);

の代わりに

properties[currentPropertyIndex] = p;

追加された後、コンシューマーがオブジェクトに変更を加えることができないように、オブジェクトを複製していると思います。それが必要かどうかは私には明らかではありません。必要な場合、その2番目のインスタンス化は、クローニングを実装するコストです。

一方、各addPropertyのメソッド本体を書き直した場合、必要なオブジェクト初期化は1つだけです。

onlyを使用して2番目または3番目のメソッドを使用する場合、2番目のインスタンス化を回避できますが、データのセット(一緒に属する)をラップすることをお勧めします)とにかくオブジェクトで。優れた慣行に準拠すると、本質的に二重初期化に戻ります。この二重初期化は、パフォーマンスのレッドフラグではありません(コンストラクターの本体に大きなリフトがないことを前提としています)。

1つのオブジェクトのインスタンス化を回避するというパフォーマンスの議論は、長いシグネチャを持つメソッドを使用することの可読性や一般的な開発が容易ではない結果と比較すると、かなり暗いです。

大規模なアプリケーションでは、これによりパフォーマンスが向上するか、ガベージコレクションの速度が低下しますか?

一般的にそれを避けるべきではありません。パフォーマンスを絞り込んでいない限り、これらの種類の考慮事項により、コードベース(もしあれば)を無視してコードベースを不必要に複雑にします。

時期尚早に最適化しないでください。パフォーマンスの問題があるときに最適化します。後者はあなたがとにかく問題になることは決してないかもしれないものを修正するための無駄な努力につながるので、あなたが考えることができるどんな問題よりも実際に発生する問題を解決する方が良いです。

0
Flater