長いパラメーターリストと長い状態変数リスト


10

C ++の本では、ほとんどのパラメーターはクラスの状態変数にリファクタリングできるため、長いパラメーターリストを持つ関数は必要なくなったと著者は述べています。一方、関数型プログラミングの本は、状態変数はバグが発生しやすくコードの並列化が困難な副作用を引き起こすため、悪であると述べています。私は困惑しています。コードは、状態変数を関数パラメーターリストに移動することにより、可能な限り状態変数に依存しないようにする必要がありますか?


オリジナルの本はC ++が関数型言語であるとコメントしていましたか?
マーティンヨーク

回答:


7

proceduralまたはfunctionalパラダイムでプログラミングしているかどうかに依存します。前者にはミュータブルな状態が必要であり、後者には障害があります。これはリンゴとオレンジです。彼らは両方ともバイリウィックで正しいです!

単一の割り当てやその他の機能的手法を命令型の手続き型言語に適用できます。不変状態では並行プログラミングがより確定的になりますが、JavaやC ++などの言語ですべてのオブジェクトを不変にすることは、そのメモリモデルがこのパラダイムを簡単にサポートしないため、ほとんど不可能です。


:ありがとう!本<<すべてのプログラマーが知っておくべき97のこと>>は、副作用を回避するなどの関数型プログラミングの原則を適用する必要があると述べています。命令型のコードコンテキストで関数型プログラミングの原則を適用することはできませんか?
TomCaps、2011

手続き型プログラミングでは状態は必要ありません 。これは一般的ですが、必須ではありません。それが一般的であることは、何よりも習慣によるものです。ただし、(状態)変数を保持する方が他の方法(非同期処理など)よりも簡単な場合もあることは認めます。
Marjan Venema、2011

不変の変数を持つ@Marjan何でも状態です

@ジャロッド:今、あなたは私を混乱させました。もう一度お読みください「ミュータブル状態が必要です」の「ミュータブル」を見逃してしまいました。しかし、あなたのコメントは不変の変数を持つことが状態であると言っているようです。わかりません。私はこれらの用語で変更可能で不変であることに振り回して考えていることに慣れていないためかもしれません。私が読むための参考文献はありますか?
Marjan Venema 2011

@MarjanVenema:はい、不変変数を持つことは状態です。手続き型プログラミングと関数型プログラミングの状態の処理の違いは、proc.progではありません。状態があり、機能はありません-むしろ、違いはそのプロシージャです。prog。状態は変更可能ですが、(純粋な)関数型プログラミングでは状態は常に不変です。たとえばen.wikipedia.org/wiki/Purely_functionalを参照してください。これは、純粋に関数型の言語が更新を回避することを説明しています。
sleske 2011

1

私があなたの質問を正しく理解している場合、パラメーターまたはクラス変数/メンバー/フィールド/などの使用を修飾する条件は何ですか?関数ではなくメソッドを参照していると思います。これが特にC ++に関するものである場合は、質問をスタックオーバーフローに移動することをお勧めします。

長いパラメーターリストは、メソッドをより詳細なものにリファクタリングする必要があることを示している可能性があります。一般に、パラメーターを使用すると、コードの結合が緩くなります。これが最近のほとんどのオブジェクト指向言語に当てはまるかどうかはわかりませんが、特に多くのクラス変数が関係している場合は、オブジェクトの作成にコストがかかる可能性があります。したがって、クラス変数がオブジェクトであり、プログラムで頻繁に参照されている場合、それらはクラス変数であると正当化される可能性があります。

また:

  • 他のメソッドがクラス変数を利用できますか?はいの場合は、クラス変数の使用を検討してください。
  • メソッドは公開されていますか?公開する場合は、パラメーターを使用します。
  • パラメータリストをハッシュ/マップ/配列/コレクション/リスト/などとして適切に表すことができますか?もしそうなら、それをオプションと考えてください。
  • メソッドは静的ですか?はいの場合、パラメータを使用します。

0

いいえ、状態変数自体副作用を引き起こしません

(他の場所に表示されるデータ構造で)セッターメソッドを呼び出す、副作用が発生します。

データ構造を使用して、長いパラメーターリストと非表示を非表示にすることができますが、それに応じて構築すると、副作用を回避できます。以下に小さな例を示します(Javaの場合、テストされていません)。

class ManyParams {
    final String theName = null;
    final int    theAge = 0:
    ManyParams() {}
    ManyParams(String a, int b) { theName=a; theAge = b; }
    public withName(String n) {
        return new ManyParams(n, this.theAge);
    }
    public withAge(int i) {
         return new ManyParams(theName, i);
    }
}
/// to be used like this
foo(new ManyParams.withName("John").withAge(42));

もちろん、ManyParamsのコンストラクターは、この方法でも長いパラメーターリストを保持します。しかし、その隠された。

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