web-dev-qa-db-ja.com

状態、可変状態、不変状態とは何ですか?

これは初心者向けの質問ですが、Googleで初心者に十分な答えを見つけることができませんでした。

人々が「状態」と言うとき、人々は何を意味しますか-一般的なプログラミング、そしてOOプログラミングで具体的には?

また、ミュータブルステートとイミュータブルステートとは何ですか?繰り返しになりますが、一般的にはプログラミングで、具体的にはOOPでも?

34
Aviv Cohn

値(数値、文字列、複雑なデータ構造)をIDと特定の時点に関連付けると、状態になります。

たとえば、数字10自体は状態を表していません。明確に定義された数字であり、常に自然数10になります。別の例として、文字列 "HELLO"は5文字のシーケンスであり、それは、含まれる文字とそれらが現れる順序によって完全に記述されます。 500万年後も、文字列 "HELLO"は文字列 "HELLO"のままです。これは純粋な値です。

状態を持つためには、これらの純粋な値がidentityを所有するある種のエンティティに関連付けられている世界を考慮する必要があります。アイデンティティーは原始的なアイデアです。つまり、他のプロパティに関係なく、2つのものを区別できるということです。たとえば、同じモデル、同じ色の2台の車は、2台の異なる車です。

これらにアイデンティティを指定すると、純粋な値で記述されたプロパティをそれらに付加できます。たとえば、私の車は青くなる特性を持っています。この事実はペアを関連付けることで説明できます

("colour", "blue")

私の車に。ペア(「色」、「青」)は、その特定の車のstateを表す純粋な値です。

状態は特定のエンティティに関連付けられるだけでなく、特定の時点にも関連付けられます。つまり、今日、私の車には状態があります

("colour", "blue")

明日私はそれを黒く塗り直し、新しい状態になります

("colour", "black")

エンティティの状態は変化する可能性がありますが、そのアイデンティティは定義により変化しないことに注意してください。もちろん、実体が存在する限り、もちろん、車は作成されて破壊される可能性がありますが、その寿命を通じてそのアイデンティティを維持します。まだ存在しないもののアイデンティティについて話すことは意味がありません。

特定のエンティティに関連付けられているプロパティの値が時間の経過とともに変化する場合、そのエンティティの状態はmutableであると言います。そうでなければ、状態はimmutableであると言います。

最も一般的な実装は、エンティティの状態をある種の変数(グローバル変数、オブジェクトメンバー変数)に保存することです。つまり、現在のスナップショットを保存します状態の。変更可能な状態は、割り当てを使用して実装されます。割り当て操作ごとに、以前のスナップショットが新しいスナップショットに置き換えられます。このソリューションは通常、メモリの場所を使用して現在のスナップショットを保存します。メモリ位置の上書きは、スナップショットを新しいものに置き換える破壊的な操作です。 ( ここ あなたはこの場所指向プログラミングアプローチについての興味深い話を見つけることができます。)

別の方法は、エンティティの後続の状態(履歴)を値のストリーム(おそらく無限シーケンス)として表示することです。 SICPの第3章 。この場合、各スナップショットは異なるメモリ位置に保存され、プログラムは同時に異なるスナップショットを検査できます。未使用のスナップショットは、不要になったときにガベージコレクションすることができます。

2つのアプローチの長所/短所

  • アプローチ1はメモリの消費量が少なく、コピーを含まないため、新しいスナップショットをより効率的に構築できます。
  • アプローチ1は、参照を保持しているプログラムのすべての部分に新しい状態を暗黙的にプッシュします。アプローチ2は、スナップショットをオブザーバーにプッシュするための何らかのメカニズムを必要とします。イベントの形で。
  • アプローチ2は、一貫性のない状態エラー(部分的な状態の更新など)を防止するのに役立ちます。古い状態から新しい状態を生成する明示的な関数を定義することで、異なる時点で生成されたスナップショットを簡単に区別できます。
  • アプローチ2は、状態自体に依存しない状態に関するビューを簡単に作成できるという点で、よりモジュール化されています。 mapfilterなどの高階関数を使用する。
48
Giorgio

状態は、単にメモリに保持されているものに関する情報です。

オブジェクト指向の簡単な練習として、クラスをcookieカッター、cookieをオブジェクトと考えてください。 Cookieカッター(クラス)を使用して、Cookieを作成(オブジェクトをインスタンス化)できます。クッキーの特性の1つがその色であるとしましょう(食品の着色を使用して変更できます)。他のプロパティと同様に、そのCookieの色はその状態の一部です。

可変状態とは、オブジェクト(Cookie)を作成した後に変更できる状態です。不変状態とは、変更できない状態です。

不変オブジェクト(noneの状態を変更できる)は、concurrency、を処理するときに重要になります。同時にオブジェクト。不変性は、オブジェクトの存続期間中、状態が安定していて有効であることを信頼できることを保証します。

一般に、オブジェクトの状態は「プライベート変数またはメンバー変数」に保持され、「プロパティ」またはゲッター/セッターメソッドを通じてアクセスされます。

11
Robert Harvey

「ステート」という用語は(「メンバー変数」などの具体的なタイプのステートとは対照的に)、ステートフルなAPIとステートレスなAPIを比較するときに最も役立つと思います。 APIに言及せずに「状態」を定義しようとすることは、プログラミング言語に言及せずに「変数」または「関数」を定義しようとすることに少し似ています。正しい答えのほとんどは、単語の意味をすでに知っている人にのみ意味があります。

ステートフルvsステートレス

  • ステートフル APIは、これまでに呼び出した関数と引数を「記憶」するAPIであるため、次に関数を呼び出すときに、その情報が使用されます。 「記憶」の部分は、メンバー変数を使用して実装されることがよくありますが、それが唯一の方法ではありません。
  • stateless APIは、すべての関数呼び出しがそれに渡される引数にのみ依存し、他には何も依存しないAPIです。

たとえば、OpenGLはおそらく私が知っている最もステートフルなAPIです。ひどく単純化しすぎると、次のようになります。

glSetCurrentVertexBufferArray(vba1);
glSetCurrentVertexBufferObject(vbo1);
glSetCurrentVertexShader(vert1);
glSetCurrentFragmentShader(frag1);
// a dozen other things
glActuallyDrawStuffWithCurrentState(GL_TRIANGLES);

ほとんどすべての関数は、OpenGLが覚えておく必要のある状態の一部を渡すために使用され、最後にすべての描画を実行するために1つの対格的に単純な関数を呼び出します。

(単純化された)OpenGLのステートレスバージョンは、おそらく次のようになります。

glActuallyDrawStuff(vba1, vbo1, vert1, frag1, /* a dozen other things */, GL_TRIANGLES);

状態の少ないAPIの方が理由がわかりやすいと人々が言うのをよく耳にします。議論の数を抑えることができるなら、私は一般的にそれに同意します。

可変vs不変

私の知る限り、この区別は初期状態を指定できる場合にのみ意味があります。たとえば、C++コンストラクターを使用します。

// immutable state
ImmutableWindow windowA = new ImmutableWindow(600, 400);
windowA = new ImmutableWindow(800, 600); // to change the size, I need a whole new window

// mutable state
MutableWindow windowB = new MutableWindow(600, 400);
windowB.width = 800; // to change the size, I just alter the existing object
windowB.height = 600;

ウィンドウのサイズを「記憶」していないウィンドウクラスを実装するのは難しいでしょうが、ユーザーがウィンドウの作成後にウィンドウのサイズを変更できるようにするかどうかを決定できます。

PSでOOP「状態」は通常が「メンバー変数」を意味することは事実です、しかし、それだけではありません。たとえば、C++では、メソッドは静的変数を持つことができ、ラムダは変数をキャプチャすることによってクロージャになることができます。どちらの場合も、これらの変数は関数への複数の呼び出しにわたって持続し、おそらく次のように修飾されます状態:通常の関数のローカル変数は、それらがどのように使用されているかによって、状態と見なされる場合があります(main()で持っている変数がよくカウントされます)。

7
Ixrec

平易な言葉で

dictionary の状態:

a。状況に関する、状態または状態。

  1. 状態-主要な属性に関するものの方法。

何かの状態は、その属性が任意の瞬間に持っている値のセットです。

OOPの場合、オブジェクトの状態は、特定の瞬間におけるオブジェクトの属性値のスナップショットです。

Thing t = new Thing();
t.setColor("blue");
t.setPrice(100)
t.setSize("small");

状態は青、価格は100、サイズは小さいです。

後で行う場合:

t.setColor("red");

オブジェクトの属性の1つを変更しましたが、オブジェクトは以前と同じではなくなったため、状態全体も変更しました。

クラスは、作成後にプロパティの値を変更できないように設計されている場合があります。それらのプロパティのすべての値は、コンストラクターに渡されるか、データベースやファイルなどのソースから読み取られますが、「setter」メソッドやその他の方法がないため、それらの値を変更する方法はありません。オブジェクト内の値を変更する。

Thing t = new Thing("red",100,"small");
t.setColor("blue") -->> ERROR, the programmer didn't provide a setter or any other way to change the properties values after initialization.

これは、変更または変更できない状態と呼ばれます。できることは、オブジェクトを破棄して新しいオブジェクトを作成し、それを同じ参照または変数に割り当てることだけです。

Thing t = new Thing("red",100,"small");
t = new Thing("blue",100,"small");
// I had to create a new Thing with another color since this thing is inmutable.
2