フィールドとメソッドの引数[終了]


9

私は新しいクラスを書き始めたばかりで、厳密には必要のないメソッド引数をたくさん追加していることに気付きました。これは、クラスの一般的な構成や依存関係ではなく、特定のメソッド呼び出しに固有のクラス内の状態を回避する習慣に従っています。

そうすることは、引数を持たない可能性のある多くのメソッドが1、2、または3で終わることを意味します。

このトレードオフについてどう思うか、どのような状況でどのアプローチを取るかをどのように決定するかについて、あなたの意見を聞きたいのですが。

コードを説明するとき、コードは英語よりも理解しやすいことが多いため、両方のバリアントを含む小さな要点を作成しました:https : //gist.github.com/JeroenDeDauw/6525656


ローカル変数としてのみ使用される引数(オブジェクトの存続期間中はグローバルではない)は、意味がある限りのみスコープ内にある必要があります...非インスタンス状態をインスタンス状態として保存する場合、私はそれが便利...私の意見だけでも。実際の実行フローがわかりにくい。
最大

パラメータを使用し、メソッドの実行中に状態を変更する必要があるかどうかをクラスに処理させることで、「教えないでください」という原則にうまく結びついています。教えてはいけないことは、オブジェクトの状態(露骨なプラグイン)についてオブジェクトにクエリを実行できないことを意味しないことに
注意してください

回答:


2

この例の外部から見えるメソッドはだけなので、updateTableメソッドパラメータの代わりにフィールドを使用しても問題ないと思います。

これがより一般的なクラス(などTableTools)の一部である場合、状態を必要とするヘルパーメソッドを非表示の内部クラスに移動します。

疑似コードの例:

class TableTools {
    ...
    public void updateTable(currentTable, newTable) {
        TableUpdater u = new TableUpdater(schemaModifier, currentTable, newTable);
        u.removeRemovedFields();
        u.addAddedFields();
     }

     private class TableUpdater { ... }
}

これにより、1つのパブリックメソッドのみで使用されるフィールドを回避できます。さらに、コードは、updateTableへのすべての呼び出しがTableUpdaterの独自のコピー、つまりTableUpdaterのインスタンス変数の独自のコピーを使用するという意味でスレッドセーフです。


7

フィールドを使用すると、それらのフィールドを使用するメソッドでマルチスレッドを使用できるようになります。

このようなフィールドを使用することは、再利用性と保守性の観点からグローバルを使用するよりもほんの少しだけ優れています。ここでの重要な点は、複雑なセットアップでは、どのメソッドを使用するか、どのフィールドを使用するかについて、慎重かつ最新のドキュメントが必要であることです。引数を使用するときに必要のないもの。


マルチスレッドは、PHPのように、私のユースケースには関係ありません。フィールドの使用方法が簡単でない場合、このアプローチは悪いことであることに同意します。この場合、それらは唯一のパブリックメソッドからのみ書き込まれます(常に書き込まれます)。これが原因で問題が発生することはないと思います。このようなフィールドについては、グローバルよりもわずかに優れているだけですが、どういう意味かよくわかりません。詳しく説明できますか?
Jeroen De Dauw 2013

7

素人の言葉で:

  • メソッドは引数をできるだけ少なくする必要があります(MartinのClean Code)
  • オブジェクトの機能の1つは、状態を持つことができる(そして持つ必要がある)ものです。
  • オブジェクトの状態を操作しない、つまりすべてをパラメーターとして受け取る非静的メソッドは、まとまりがありません
  • 非まとまりのないメソッドを静的にして、ユーティリティクラスにグループ化することもできます。

繰り返しになりますが、私の考えでは、まとまりのないメソッドは、ユーティリティクラスに属し、ドメイン名を持つクラスには属しません。


1

現在のケースではフィールドを使用しないでください! オブジェクトを同時に使用する2つの「スレッド」は、互いに深刻な混乱を招きます。それらは、実際の別々のスレッドである必要もありません(したがって引用符)。オブジェクトを1つのテーブルに設定し、それを別のテーブルに使用するメソッドを呼び出してから、元の設定を使用しようとすると、問題が発生します。とりあえずパラメータを使いましょう。

何がしたいここで行うためには、一つだけの場合に使用される新しいアップデータクラスを作成することです。元のクラスには、必要に応じてインスタンスを作成するメソッドを含めることができます。新しいクラスにはフィールドがあります。あなたは両方の長所を持っています。場合によっては、パラメータのみを使用する方が簡単なことがありますが、この例では、別のクラスの方が優れている場所にすでに到達しています。


0

あなたがそれを見るように、私は、選択は実際の状況に応じてあるべきだと思います。アイテムがインスタンスに属している場合、そのフィールドとして表示されます。アイテムがインスタンスの外部にある場合は、メソッドパラメータとして渡す必要があります。

この場合、有効性(違いはとにかく取るに足らない)や(神の救い!)入力のしやすさではなく、コードの理解可能性と自然さによって導かれるべきです。


0

私の意見では、何かに何かをするコードを書いているなら、それは何をすべきかを定義するパラメータを取り、その名前はそれに対して何をするかを可能な限り定義すべきです。

あなたがアップパッケージというコードを記述している場合、アクションは何かに実行するために、あなたはそれがオブジェクトにに行われるべきものをラップし、あなたのものに渡す必要がある何かをします

このアクションは、最初のメソッドへの呼び出しの一種のメタ記述になり、後でキューに入れるか、何らかの理由でまったく実行しないことを決定することもできます。

だからあなたの質問はそれが アクションなの 関数なのか?アンアクションは延期またはキャンセル、したがって、それは時に作用することをカプセル化する必要がありますすることができます。関数は、そのトップは、そのパラメータを保存する必要はありませんすぐに起こります。

取り消しアクションはできますが、関数はできません。

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