Apa itu Negara, Negara Mutabel dan Negara Tidak Berubah?

32

Ini adalah pertanyaan pemula, tetapi saya tidak dapat menemukan jawaban yang cukup untuk pemula di Google.

Apa yang orang maksud ketika mereka mengatakan 'status' - dalam pemrograman secara umum, dan dalam pemrograman OO secara khusus?

Juga, apa yang bisa berubah dan tidak berubah - lagi, umumnya dalam pemrograman dan juga secara khusus dalam OOP?

Aviv Cohn
sumber
4
Berbagi penelitian Anda membantu semua orang . Beri tahu kami apa yang telah Anda coba dan mengapa itu tidak memenuhi kebutuhan Anda. Ini menunjukkan bahwa Anda telah meluangkan waktu untuk mencoba membantu diri sendiri, itu menyelamatkan kami dari mengulangi jawaban yang jelas, dan yang paling utama itu membantu Anda mendapatkan jawaban yang lebih spesifik dan relevan. Lihat juga Cara Meminta
nyamuk

Jawaban:

46

Anda memiliki status saat Anda mengaitkan nilai (angka, string, struktur data yang kompleks) ke identitas dan titik waktu.

Misalnya, angka 10 dengan sendirinya tidak mewakili keadaan apa pun: itu hanya angka yang terdefinisi dengan baik dan akan selalu menjadi dirinya sendiri: bilangan asli 10. Sebagai contoh lain, string "HELLO" adalah urutan lima karakter, dan itu sepenuhnya dijelaskan oleh karakter yang dikandungnya dan urutan di mana mereka muncul. Dalam lima juta tahun dari sekarang, string "HELLO" akan tetap menjadi string "HELLO": nilai murni.

Untuk memiliki negara Anda harus mempertimbangkan dunia di mana nilai-nilai murni ini terkait dengan beberapa jenis entitas yang memiliki identitas . Identitas adalah ide primitif: itu berarti Anda dapat membedakan dua hal terlepas dari properti lain yang mungkin mereka miliki. Sebagai contoh, dua mobil dengan model yang sama, warna yang sama, ... adalah dua mobil yang berbeda.

Dengan hal-hal ini dengan identitas, Anda dapat melampirkan properti padanya, dijelaskan oleh nilai-nilai murni. Misalnya, mobil saya memiliki sifat biru. Anda dapat menggambarkan fakta ini dengan mengaitkan pasangan

("colour", "blue")

ke mobil saya. Pasangan ("warna", "biru") adalah nilai murni yang menggambarkan keadaan mobil itu.

Negara tidak hanya terkait dengan entitas tertentu, tetapi juga ke titik waktu tertentu. Jadi, Anda dapat mengatakan bahwa hari ini, mobil saya memiliki status

("colour", "blue")

Besok aku akan mengecatnya dalam warna hitam dan negara baru akan melakukannya

("colour", "black")

Perhatikan bahwa status suatu entitas dapat berubah, tetapi identitasnya tidak berubah menurut definisi. Ya, selama entitas itu ada, tentu saja: sebuah mobil dapat dibuat dan dihancurkan, tetapi ia akan mempertahankan identitasnya sepanjang masa hidupnya. Tidak masuk akal untuk berbicara tentang identitas sesuatu yang belum ada / lagi.

Jika nilai properti yang dilampirkan pada entitas tertentu berubah seiring waktu, Anda mengatakan bahwa status entitas itu bisa berubah . Kalau tidak, Anda mengatakan bahwa negara tidak dapat diubah .

Implementasi yang paling umum adalah untuk menyimpan keadaan suatu entitas dalam beberapa jenis variabel (variabel global, variabel anggota objek), yaitu untuk menyimpan snapshot keadaan saat ini. Keadaan yang tidak dapat diubah kemudian diimplementasikan menggunakan penugasan: setiap operasi penugasan menggantikan foto sebelumnya dengan yang baru. Solusi ini biasanya menggunakan lokasi memori untuk menyimpan snapshot saat ini. Menimpa lokasi memori adalah operasi destruktif yang menggantikan snapshot dengan yang baru. ( Di sini Anda dapat menemukan pembicaraan yang menarik tentang pendekatan pemrograman berorientasi tempat ini .)

Alternatifnya adalah dengan melihat status (histori) selanjutnya dari suatu entitas sebagai aliran (barangkali urutan tak terbatas) dari nilai-nilai, lihat misalnya Bab 3 dari SICP . Dalam hal ini, setiap foto disimpan di lokasi memori yang berbeda, dan program dapat memeriksa foto yang berbeda secara bersamaan. Snapshots yang tidak terpakai dapat dikumpulkan dari sampah saat tidak diperlukan lagi.

Keuntungan / kerugian dari kedua pendekatan tersebut

  • Pendekatan 1 mengkonsumsi lebih sedikit memori dan memungkinkan untuk membuat snapshot baru secara lebih efisien karena tidak melibatkan penyalinan.
  • Pendekatan 1 secara implisit mendorong negara baru ke semua bagian dari program yang memegang referensi untuk itu, pendekatan 2 akan memerlukan beberapa mekanisme untuk mendorong snapshot ke pengamatnya, misalnya dalam bentuk acara.
  • Pendekatan 2 dapat membantu untuk mencegah kesalahan kondisi tidak konsisten (mis. Pembaruan kondisi parsial): dengan mendefinisikan fungsi eksplisit yang menghasilkan status baru dari yang lama, lebih mudah untuk membedakan antara foto yang dihasilkan pada titik yang berbeda dalam waktu.
  • Pendekatan 2 lebih modular karena memungkinkan untuk dengan mudah menghasilkan tampilan pada negara yang independen dari negara itu sendiri, misalnya menggunakan fungsi tingkat tinggi seperti mapdan filter.
Giorgio
sumber
1
Perhatikan bahwa objek bukan satu-satunya hal dengan keadaan. Jika suatu program menggunakan variabel global yang dapat berubah, program itu sendiri dikatakan memiliki status. Demikian juga, jika suatu fungsi memiliki variabel yang mengingat nilai di seluruh panggilan fungsi, fungsi tersebut stateful.
Doval
2
@Doval: Anda dapat menganggap negara global sebagai keadaan objek dunia global. Sejauh yang saya tahu, tampilan ini digunakan misalnya di Ruby. Fungsi yang mengingat status isomorfik untuk objek hanya dengan satu metode. Ide dasar yang umum adalah bahwa Anda mengaitkan nilai dengan identitas, atau tempat, yaitu bahwa hal-hal tertentu dapat menyimpan nilai (mungkin nilai yang bisa berubah) tetapi mempertahankan identitas mereka.
Giorgio
3
Tentu, saya setuju secara prinsip. Saya hanya memastikan Prog memahami bahwa status bukan sesuatu yang eksklusif untuk OOP. Saya tidak berpikir alur pemikiran "semuanya adalah objek" muncul secara alami.
Doval
@Doval: Anda menyebutkan fungsi stateful yang mengingat nilai di berbagai panggilan. Salah satu contoh yang dapat saya pikirkan adalah variabel lokal statis dalam C. Contoh lain adalah penutupan (fungsi yang menangkap variabel yang ditentukan dalam konteksnya). Penutupan agak ganda untuk objek: penutupan adalah objek dengan tepat satu metode, sedangkan objek adalah kumpulan penutupan yang didefinisikan atas variabel yang sama. Anda mungkin tahu semua ini, tetapi saya ingin meringkasnya di sini. Secara umum, Anda dapat menyimpan status di beberapa lokasi memori dan mengaksesnya menggunakan mekanisme yang berbeda, seperti yang Anda tunjukkan.
Giorgio
11

Negara hanyalah informasi tentang sesuatu yang tersimpan dalam ingatan.

Sebagai latihan sederhana dalam orientasi objek, pikirkan kelas sebagai pemotong kue, dan cookie sebagai objek. Anda dapat membuat cookie (instantiate objek) menggunakan cookie cutter (kelas). Katakanlah salah satu sifat cookie adalah warnanya (yang dapat diubah dengan menggunakan pewarna makanan). Warna cookie itu adalah bagian dari kondisinya, seperti properti lainnya.

Keadaan tidak berubah adalah keadaan yang dapat diubah setelah Anda membuat objek (cookie). Keadaan abadi adalah keadaan yang tidak bisa diubah.

Objek yang tidak dapat diubah (yang tidak dapat diubah oleh negara bagian) menjadi penting ketika Anda berurusan dengan konkurensi, kemampuan lebih dari satu prosesor di komputer Anda untuk beroperasi pada objek itu secara bersamaan. Immutability menjamin bahwa Anda dapat mengandalkan negara agar stabil dan valid selama masa pakai objek.

Secara umum, keadaan suatu objek disimpan dalam "variabel pribadi atau anggota," dan diakses melalui "properti" atau metode pengambil / penyetel.

Robert Harvey
sumber
3
Demi manfaat Prog, fakta bahwa suatu nilai tidak pernah berubah juga penting karena jauh lebih mudah untuk dipikirkan. Ini dapat digunakan dalam banyak fungsi / metode yang Anda inginkan dan Anda tahu mereka tidak dapat mengubahnya. Dengan keadaan bisa berubah Anda harus melacak sejarah bagaimana objek itu digunakan untuk mencari tahu apa nilainya sekarang . Itu overhead mental yang tidak perlu jika membuatnya abadi tidak menyulitkan program.
Doval
Terimakasih telah menjawab. Jadi pada dasarnya, di OOP, ketika seseorang mengatakan 'status', mereka biasanya berarti "variabel anggota objek"? Jika demikian, maka 'keadaan tidak berubah' adalah variabel publik, atau lebih umum di OOP, variabel pribadi yang dapat diubah melalui metode penyetel - sementara 'keadaan tidak berubah' hanyalah variabel anggota pribadi?
Aviv Cohn
1
Ketidakmampuan dapat disimulasikan dengan hanya tidak pernah menulis ke anggota pribadi suatu objek setelah mereka diisi dengan nilai awal. Kekekalan dapat ditegakkan dengan menggunakan sejumlah metode: tidak menyediakan metode penyetel, membutuhkan nilai awal untuk ditetapkan menggunakan parameter konstruktor, menulis dalam gaya fungsional, menggunakan konstanta, dll.
Robert Harvey
1
Saya menganggap negara sebagai nilai dari beberapa properti beberapa entitas. "Dikirimkan" adalah suatu keadaan. Begitu juga "Tarif Pajak." Berat sesuatu adalah suatu keadaan. Apakah Anda sedang bangun atau tidur adalah keadaan. Warna sesuatu adalah suatu keadaan. Informasi yang bermakna tentang sesuatu, disimpan dalam semacam memori komputer.
Robert Harvey
1
Dalam banyak bahasa, kekekalan dapat ditegakkan dengan mendeklarasikan variabel anggota sebagai "const" atau "final". Variabel seperti itu hanya dapat diinisialisasi oleh konstruktor. Jangan berasumsi bahwa variabel pribadi tidak dapat diubah - mereka masih dapat dimodifikasi oleh fungsi anggota kelas sendiri (metode).
Simon B
7

Saya pikir istilah "negara" (sebagai lawan dari jenis negara konkret seperti "variabel anggota") paling berguna ketika membandingkan API stateful dengan yang tanpa negara. Mencoba mendefinisikan "keadaan" tanpa menyebutkan API sedikit seperti mencoba mendefinisikan "variabel" atau "fungsi" tanpa menyebutkan bahasa pemrograman; sebagian besar jawaban yang benar hanya masuk akal bagi orang-orang yang sudah tahu apa arti kata-kata itu.

Stateful vs Stateless

  • Sebuah stateful API adalah salah satu yang "ingat" fungsi apa yang telah Anda disebut sejauh ini dan dengan argumen apa, sehingga waktu berikutnya Anda memanggil fungsi itu akan menggunakan informasi tersebut. Bagian "mengingat" sering diterapkan dengan variabel anggota, tetapi itu bukan satu-satunya cara.
  • Sebuah stateless API adalah salah satu di mana setiap fungsi panggilan semata-mata tergantung pada argumen berlalu untuk itu, dan tidak ada lagi.

Sebagai contoh, OpenGL mungkin adalah API paling stateful yang saya tahu. Jika saya mungkin terlalu sederhana menyederhanakannya, kita mungkin mengatakan itu terlihat seperti ini:

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

Hampir setiap fungsi hanya digunakan untuk melewati beberapa keadaan yang perlu diingat OpenGL, maka pada akhirnya Anda memanggil satu fungsi antiklimaks yang sederhana untuk melakukan semua gambar.

Versi OpenGL (disederhanakan) tanpa kewarganegaraan mungkin akan terlihat lebih seperti ini:

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

Anda akan sering mendengar orang mengatakan bahwa API dengan status yang lebih sedikit lebih mudah untuk dipikirkan. Jika Anda dapat menjaga agar jumlah argumen tetap terkendali, saya biasanya setuju dengan itu.

Berubah vs Tidak Berubah

Sejauh yang saya tahu, perbedaan ini hanya bermakna ketika Anda dapat menentukan kondisi awal . Misalnya, menggunakan konstruktor 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;

Akan sulit untuk menerapkan kelas jendela yang tidak "mengingat" ukuran apa itu, tetapi Anda dapat memutuskan apakah pengguna harus dapat mengubah ukuran jendela setelah membuatnya.

PS Dalam OOP memang benar bahwa "negara" biasanya berarti "variabel anggota", tetapi bisa lebih dari itu. Misalnya, dalam C ++, suatu metode dapat memiliki variabel statis, dan lambdas dapat menjadi penutupan dengan menangkap variabel. Dalam kedua kasus variabel-variabel tersebut bertahan di beberapa panggilan ke fungsi dan dengan demikian mungkin memenuhi syarat sebagai negara. Variabel lokal dalam fungsi reguler juga dapat dianggap status tergantung pada bagaimana mereka digunakan (yang saya punya di main () sering dihitung).

Ixrec
sumber
Jawaban yang mengagumkan. Terima kasih banyak, Anda benar-benar membantu saya mengambil ini dengan cepat. Sedikit yang saya tahu, saya sudah bekerja dengan ini untuk waktu yang lama dan tidak tahu apa namanya.
the_endian
2

Dengan kata-kata awam

The Kamus negara:

Sebuah. Suatu kondisi atau cara hidup, sehubungan dengan keadaan.

  1. negara - cara sesuatu sehubungan dengan atribut utamanya;

Keadaan sesuatu adalah himpunan nilai yang dimiliki atributnya pada saat tertentu.

Dalam OOP, keadaan suatu objek adalah potret dari nilai-nilai atributnya pada saat tertentu.

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

Keadaannya adalah warnanya yang biru, harganya 100 dan ukurannya kecil.

Jika nanti Anda lakukan:

t.setColor("red");

Anda mengubah salah satu atributnya tetapi Anda juga mengubah keadaan secara keseluruhan karena objek tidak lagi sama seperti sebelumnya.

Terkadang kelas dirancang sehingga nilai propertinya tidak dapat diubah setelah dibuat. Semua nilai properti mereka diteruskan ke konstruktor atau dibaca dari beberapa sumber seperti database atau file, tetapi tidak ada cara untuk mengubah nilai-nilai itu setelah saat itu, karena tidak ada metode "setter", atau cara lain untuk mengubah nilai di dalam objek.

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.

Itu disebut keadaan yang tidak bisa diubah dari bermutasi. Yang bisa Anda lakukan adalah menghancurkan objek, membuat yang baru dan menganggapnya dengan referensi atau variabel yang sama.

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.
Tulains Córdova
sumber