Mengapa kita membutuhkan variabel pribadi?

210

Mengapa kita membutuhkan variabel pribadi di kelas?

Setiap buku tentang pemrograman yang saya baca mengatakan ini adalah variabel pribadi, beginilah cara Anda mendefinisikannya tetapi berhenti di situ.

Kata-kata dari penjelasan ini selalu tampak bagi saya seolah-olah kita benar-benar memiliki krisis kepercayaan terhadap profesi kita. Penjelasan selalu terdengar seperti programmer lain keluar untuk mengacaukan kode kita. Namun, ada banyak bahasa pemrograman yang tidak memiliki variabel pribadi.

  1. Apa yang bisa dicegah oleh variabel pribadi?

  2. Bagaimana Anda memutuskan apakah properti tertentu harus pribadi atau tidak? Jika secara default setiap bidang HARUS bersifat pribadi maka mengapa ada anggota data publik di kelas?

  3. Dalam keadaan apa suatu variabel harus dipublikasikan?

mwallace
sumber
9
Pertanyaan Anda terdengar sangat agnostik-bahasa, tetapi Anda telah menandainya sebagai java dan c ++. Jika Anda tertarik pada perspektif dari luar kedua bahasa itu, Anda mungkin harus mengatakannya.
James
8
Sebagai catatan, membuat metode pribadi tidak meningkatkan "keamanan". Bagian lain dari aplikasi Anda masih dapat mengakses anggota pribadi menggunakan refleksi.
kba
3
Penggunaan dan perbedaan variabel pribadi dan publik, dan mengapa kita memilikinya, hanya dapat dipahami dalam konteks prinsip-prinsip berorientasi objek umum. Itu tidak dapat dipahami secara terpisah. Anda mungkin perlu melihatnya dari perspektif itu, hal-hal mungkin menjadi lebih jelas.
Nazar Merza
1
kemungkinan rangkap dari When
is
3
Jika Anda menangkap seseorang menggunakan sabuk pengaman di mobil mereka, Anda harus mengambil SIM mereka, karena jelas mereka tidak percaya kemampuan mereka sendiri untuk mengemudi.
gnasher729

Jawaban:

307

Ini bukan masalah kepercayaan, tapi lebih pada pengelolaan kompleksitas.

Anggota publik dapat diakses dari luar kelas, yang karena pertimbangan praktis berarti "berpotensi di mana saja". Jika ada yang salah dengan bidang publik, pelakunya bisa berada di mana saja, jadi untuk melacak bug, Anda mungkin harus melihat cukup banyak kode.

Anggota pribadi, sebaliknya, hanya dapat diakses dari dalam kelas yang sama, jadi jika ada yang salah dengan itu, biasanya hanya ada satu file sumber untuk dilihat. Jika Anda memiliki sejuta baris kode dalam proyek Anda, tetapi kelas Anda tetap kecil, ini dapat mengurangi upaya pelacakan bug Anda dengan faktor 1000.

Keunggulan lain terkait dengan konsep 'kopling'. Seorang anggota masyarakat mdari kelas Ayang digunakan oleh kelas lain Bmemperkenalkan ketergantungan: jika Anda mengubah mdalam A, Anda juga harus memeriksa penggunaan dari mdalam B. Lebih buruk lagi, tidak ada di kelas yang Amemberitahu Anda di mana msedang digunakan, jadi sekali lagi Anda harus mencari melalui seluruh basis kode; jika itu adalah perpustakaan yang Anda tulis, Anda bahkan harus memastikan kode di luarproyek Anda tidak rusak karena perubahan Anda. Dalam praktiknya, perpustakaan cenderung tetap menggunakan tanda tangan metode asli mereka selama mungkin, tidak peduli seberapa menyakitkan, dan kemudian memperkenalkan blok pemecahan perubahan dengan pembaruan versi utama. Dengan anggota pribadi, sebaliknya, Anda dapat mengecualikan dependensi segera - mereka tidak dapat diakses dari luar, sehingga semua dependensi terkandung di dalam kelas.

Dalam konteks ini, "programmer lain" termasuk masa depan dan diri Anda sebelumnya. Kemungkinannya adalah Anda tahu sekarang bahwa Anda tidak boleh melakukan hal ini X dengan variabel Y Anda, tetapi Anda pasti sudah lupa tiga bulan kemudian ketika seorang pelanggan sangat membutuhkan Anda untuk mengimplementasikan beberapa fitur, dan Anda bertanya-tanya mengapa melakukan X break Y dengan cara yang tidak jelas.

Jadi, ketika Anda harus membuat hal-hal pribadi: Saya katakan menjadikan semuanya pribadi secara default, dan kemudian hanya mengekspos bagian-bagian yang benar-benar harus publik. Semakin Anda dapat membuat pribadi, semakin baik.

tammmer
sumber
24
Memberi +1 pada inti masalah, meskipun saya pribadi menemukan kode saya lebih mudah dipelihara ketika saya berhenti melalui simpai hanya untuk memastikan bahwa variabel yang sering digunakan tetap pribadi. Tentu kesalahan mungkin muncul di masa depan, tetapi 60 baris kode kurang untuk menyaring, dan lebih sedikit variabel dan fungsi untuk boot;)
Jeffrey Sweeney
48
Cawan suci komputasi modern adalah menjaga kompleksitas.
1
Saya selalu suka mengatakan bahwa bagian dari debugging tidak hanya mengarahkan langsung ke "apa yang salah," tetapi mengambil proses bundaran mencari tahu "apa yang tidak salah," dan memfokuskan penyelidikan saya pada apa yang tersisa. Jika saya bisa mendapatkan kompiler untuk membantu saya dengan alat-alat seperti variabel pribadi untuk mendefinisikan "apa yang tidak mungkin terjadi," yang menghemat banyak waktu. Hanya dalam kasus-kasus langka di mana saya membuktikan bahwa apa yang salah tidak dapat terjadi, saya harus menggali asumsi yang lebih menakutkan, seperti mungkin buffer overrun yang menimpa data pribadi saya.
Cort Ammon
2
Tepat seperti itu. Ketika orang mendengar "menyembunyikan informasi", mereka berpikir bahwa mereka harus menggunakan variabel pribadi untuk hal-hal seperti kunci enkripsi, kredensial database, dll.
Wayne Werner
2
@AdamZerner lihat "Katakan, jangan tanya" ( martinfowler.com/bliki/TellDontAsk.html ) tentang memiliki pengambil / setter di tempat pertama - tetapi sebaliknya ya, karena Anda harus bebas untuk mengubah representasi internal dari nilai kapan saja Kamu berharap. Seperti biasa, ada pengecualian ... (mis. DTO)
gandakan Anda
111

Variabel pribadi membantu mencegah orang bergantung pada bagian tertentu dari kode Anda. Misalnya, Anda ingin menerapkan beberapa struktur data. Anda ingin pengguna struktur data Anda tidak peduli bagaimana Anda menerapkannya, tetapi hanya menggunakan implementasi melalui antarmuka Anda yang jelas. Alasannya adalah bahwa jika tidak ada yang bergantung pada implementasi Anda, Anda dapat mengubahnya kapan pun Anda inginkan. Misalnya, Anda dapat mengubah implementasi back-end untuk meningkatkan kinerja. Pengembang lain yang bergantung pada implementasi Anda akan rusak, sedangkan pengguna antarmuka akan baik-baik saja. Memiliki fleksibilitas untuk mengubah implementasi tanpa mempengaruhi pengguna kelas adalah manfaat besar yang menggunakan variabel pribadi (dan lebih luas, enkapsulasi ) memberi Anda.

Juga, ini sebenarnya bukan "krisis kepercayaan". Jika Anda membuat sepotong data untuk publik, Anda tidak dapat memastikan bahwa tidak ada yang bergantung padanya. Seringkali sangat nyaman untuk bergantung pada beberapa variabel implementasi spesifik, alih-alih melalui antarmuka publik, terutama di tengah tenggat waktu. Lebih jauh, pengembang tidak akan selalu menyadari bahwa mereka bergantung pada sesuatu yang mungkin berubah.

Jadi jawaban semacam ini untuk pertanyaan Anda yang lain, saya harap. Semua detail implementasi Anda harus pribadi, dan bagian publik harus berupa antarmuka kecil, ringkas, dan terdefinisi dengan baik untuk menggunakan kelas Anda.

Oleksi
sumber
24
IMO juga tentang komunikasi antara penulis lib dan konsumen lib. Antarmuka publik seperti "gunakan ini" dan privat seperti "jangan gunakan itu" kecuali bahwa di Jawa, Anda benar - benar tidak dapat menggunakannya secara tidak sengaja jika menjadikannya pribadi sehingga lebih aman dan lebih jelas seperti itu.
chakrit
5
@chakrit dan lainnya: Perhatikan bahwa mereka yang benar-benar keluar untuk menggunakan bidang dan metode pribadi Anda dapat melakukannya (melalui refleksi). privatekurang dari "tidak ditujukan terutama untuk keamanan", tidak memberikan "keamanan" untuk dibicarakan. Itu hanya petunjuk kuat (dikirim melalui kompiler) untuk tidak mengaksesnya.
@delnan perhatikan frasa "tidak sengaja" ya mungkin aku harus lebih jelas tentang itu.
chakrit
@chakrit Ya, saya tidak bermaksud mengatakan bahwa Anda salah. Saya hanya ingin mempromosikan hal itu.
1
@delnan: Bidang pribadi, dalam beberapa bahasa, menyediakan bentuk keamanan tertentu. Sebagai contoh, lihat jawaban Eric Lippert untuk Apakah tingkat akses dan pengubah (pribadi, disegel, dll) melayani tujuan keamanan dalam C #? .
Brian
25

Kata kunci di sini adalah Enkapsulasi . Dalam OOP Anda ingin menggunakan variabel pribadi untuk menegakkan enkapsulasi objek / kelas Anda.

Sementara programmer lain tidak keluar untuk mendapatkan Anda, mereka berinteraksi dengan kode Anda. Jika Anda tidak membuat variabel menjadi privat, mereka mungkin merujuknya ke dalam kode mereka sendiri tanpa ingin membahayakan sama sekali. Namun, jika Anda perlu kembali ke kelas dan mengubah sesuatu, Anda tidak lagi tahu siapa yang menggunakan variabel mana dan di mana. Tujuan enkapsulasi adalah untuk membuat antarmuka eksternal kelas eksplisit sehingga Anda hanya tahu metode ini (biasanya) yang bisa digunakan oleh orang lain.

  1. Oleh karena itu, variabel pribadi memastikan bahwa variabel yang sesuai tetap berada di kelas pendefinisian saja. Jika Anda perlu mengubahnya, perubahan itu bersifat lokal ke kelas itu sendiri.

  2. Dalam bahasa tradisional seperti C ++ atau Java, Anda biasanya membuat semuanya pribadi dan hanya dapat diakses oleh getter dan setter yang sesuai. Tidak perlu memutuskan banyak kok.

  3. Terkadang, f.ex. dalam C ++ struct, Anda perlu kelas hanya sebagai cara untuk mengelompokkan beberapa hal bersama. Misalnya, pertimbangkan kelas vektor yang hanya memiliki atribut xdan yatribut. Dalam kasus tersebut, Anda dapat mengizinkan akses langsung ke atribut ini dengan menyatakannya sebagai publik. Khususnya, Anda tidak boleh peduli jika beberapa kode di luar memodifikasi objek kelas Anda dengan secara langsung menulis nilai-nilai baru ke dalam xatau y.

Sebagai poin tambahan, perhatikan bahwa masalah ini dianggap sedikit berbeda dalam bahasa lain. Misalnya, bahasa yang sangat berakar dalam pemrograman fungsional menekankan ketidakmampuan data, yaitu nilai data tidak dapat diubah sama sekali. Dalam kasus seperti itu, Anda tidak perlu peduli dengan apa yang dilakukan programmer lain (atau lebih tepatnya kodenya) terhadap data Anda. Mereka tidak bisa melakukan apa pun yang dapat memengaruhi kode Anda, karena semua data tidak dapat diubah.

Oleh karena itu, dalam bahasa tersebut, Anda mendapatkan sesuatu yang disebut prinsip akses seragam , di mana orang dengan sengaja tidak membedakan metode seperti getter dan setter, tetapi menyediakan akses langsung ke variabel / fungsi. Jadi Anda dapat mengatakan bahwa deklarasi pribadi jauh lebih populer dalam skenario berorientasi objek.

Ini juga menunjukkan bagaimana memperluas pengetahuan Anda untuk memasukkan bidang lain membuat Anda melihat konsep yang ada dengan cara yang sama sekali baru.

jujur
sumber
1
+1 "Ketika programmer lain tidak keluar untuk mendapatkan Anda, mereka berinteraksi dengan kode Anda." Pemrogram yang menggunakan kode Anda pada dasarnya tidak jahat. Dengan menggunakan variabel pribadi Anda memastikan bahwa mereka (dan Anda, di masa depan) tidak terluka menggunakan kode. Ini juga membantu Anda merancang API yang lebih baik dan mendokumentasikannya.
szalski
7

Variabel pribadi memastikan bahwa referensi nanti di luar lingkup objek atau fungsi tidak akan secara tidak sengaja mempengaruhi variabel lain. Untuk proyek pemrograman besar, ini dapat membantu menghindari banyak masalah menarik (yang biasanya tidak ditangkap oleh kompiler).

Misalnya, bahasa prototipe seperti Javascript dapat memungkinkan pengguna untuk menempelkan variabel sesuai keinginan mereka:

function SomeObject() {
    this.a = 2; //Public (well, actually protected) variable

    this.showA = function() {
        alert(this.a);
    }
}

//Some lines down...

var obj = new SomeObject();
obj.a = 3;
obj.showA(); //Will alert 3. Uh oh!

Jika variabel itu bersifat pribadi, itu tidak akan dapat diubah dari luar:

function SomeObject() {
    var a = 2; //Private variable

    this.showA = function() {
        alert(a);
    }
}

//Some lines down...

var obj = new SomeObject();
obj.a = 3;
obj.showA(); //Will alert 2

Yang mengatakan, tidak semua variabel harus pribadi dan penggunaan variabel pribadi yang berlebihan sebenarnya dapat membuat kode lebih rumit. Bidang sepele yang tidak berdampak serius pada objek tidak perlu get()dan set()metode.

Variabel pribadi juga memudahkan untuk memperluas kode di masa mendatang, tanpa bergantung pada dokumentasi yang berat tentang apa yang dilakukan oleh banyak variabel publik. Ada sedikit ancaman kerusakan fungsionalitas jika lebih sedikit variabel dapat ditimpa.

Variabel publik harus digunakan ketika suatu objek / fungsi akan mengakses objek / fungsi lain, karena sebagai aturan, variabel pribadi tidak dapat melakukan ini. Anda mungkin memiliki beberapa variabel publik hingga dari beberapa variabel, dan itu bukan hal yang buruk untuk menggunakannya jika mereka digunakan dengan benar.

Jeffrey Sweeney
sumber
Tidak jelas mengapa memperingatkan 3 akan menjadi "uh oh!" pada kasus ini. Mungkin itulah yang diinginkan oleh programmer.
immibis
@immibis Mungkin, dan mungkin saya harus menjelaskan lebih dalam. Tetapi akses ke properti dapat membuka pintu karena melanggar beberapa prinsip OOP seperti prinsip buka-tutup atau LoD, karena Anda berpotensi mengekspos detail implementasi. Tentu saja tergantung pada apa properti itu sebenarnya. Sebagian besar bahasa menggunakan objek sebagai referensi, dan ketika referensi objek bisa dilewatkan dan sesama devs diam-diam mengubah properti, itu bisa BENAR-BENAR sulit untuk di-debug. IMO jauh lebih mudah dan lebih bisa dikembangkan untuk bekerja dengan metode jika Anda memiliki instance kelas.
Jeffrey Sweeney
7

Ada beberapa jawaban yang bagus mengutip manfaat untuk pemelihara dan pengguna kelas di masa depan. Namun, ada juga manfaat dari desain aslinya. Ini memberikan titik demarkasi yang jelas antara kapan tujuan Anda adalah untuk membuat segalanya lebih mudah pada diri Anda sendiri, dan ketika tujuan Anda adalah untuk membuat segalanya lebih mudah pada pengguna kelas. Ketika Anda memilih antara publik dan pribadi, itu memberi sinyal ke otak Anda untuk beralih ke satu mode atau yang lain, dan Anda berakhir dengan API yang lebih baik.

Bukannya bahasa tanpa privasi membuat desain seperti itu tidak mungkin, hanya saja kecil kemungkinannya. Alih-alih diminta untuk menulis sesuatu seperti foo.getBar(), orang-orang cenderung berpikir rajin rajin, karena lebih mudah untuk menulis foo.bar, tetapi kemudian keputusan itu tidak ditinjau kembali ketika Anda kemudian berakhir dengan monstrositas yang lebih panjang seperti obj.container[baz].foo.bar. Pemrogram yang belum pernah bekerja dalam bahasa yang lebih ketat mungkin bahkan tidak melihat apa yang salah dengan itu.

Itu sebabnya dalam bahasa tanpa privasi orang akan sering mengadopsi standar penamaan yang mensimulasikannya, seperti menambahkan garis bawah ke semua anggota "pribadi". Ini adalah sinyal yang berguna bahkan ketika bahasa tidak memberlakukannya.

Karl Bielefeldt
sumber
3

Semua variabel harus pribadi kecuali mereka benar-benar harus publik (yang hampir tidak pernah, Anda harus menggunakan properti / getter dan setter).

Variabel sebagian besar menyediakan keadaan objek, dan variabel pribadi mencegah orang lain masuk dan mengubah keadaan objek.

bbb
sumber
5
Pandangan yang terlalu sempit tentang pokok bahasan. Ada kasus-kasus di mana akses lapangan publik dijamin, bahkan lebih disukai
Roland Tepp
Seseorang tentu dapat mendesain objek yang kondisinya tidak dapat diubah (objek yang tidak dapat diubah), tetapi ini bukan aturan umum yang diterapkan pada semua kelas. Dalam pengalaman saya, sebagian besar objek membuatnya sangat mudah bagi orang lain untuk mengubah keadaan objek.
David K
1
@ DavidvidK Mungkin yang ingin dikatakan bbb adalah bahwa "variabel pribadi mencegah orang lain masuk dan tanpa pandang bulu mengubah keadaan objek." Metode publik dapat mengubah keadaan pribadi objek, tetapi hanya dengan cara yang diperlukan dan konsisten untuk fungsi objek.
Max Nanasy
@ Max Nanasy: Ya, seseorang dapat mengontrol bagaimana keadaan diubah ketika seseorang hanya menawarkan metode di antarmuka publik. Misalnya, mungkin ada hubungan di antara anggota yang harus dipenuhi agar objek menjadi "konsisten", dan Anda dapat membiarkan kondisi konsisten diri diubah hanya ke kondisi konsisten diri lainnya. Jika semua variabel itu bersifat publik maka Anda tidak dapat menegakkan ini. Tetapi bisa juga ada benda-benda di mana Anda tidak ingin mengizinkan perubahan apa pun , jadi penting untuk memperjelas hal mana yang sedang kita bicarakan.
David K
2
  • Apa yang bisa dicegah oleh variabel pribadi?

Ini tentang memperjelas properti dan metode apa yang merupakan antarmuka dan mana yang sebenarnya merupakan fungsionalitas inti. Metode / properti publik adalah tentang kode lain, sering kali kode pengembang lain menggunakan objek Anda. Saya belum pernah bekerja di tim yang terdiri dari 100+ proyek yang sama, tetapi dalam pengalaman saya mungkin tim 3-5 dengan hingga 20 pengembang lainnya menggunakan hal-hal yang saya tulis, kekhawatiran lain tampak konyol.

Catatan: Saya terutama adalah pengembang JavaScript. Saya biasanya tidak khawatir tentang pengembang lain melihat kode saya, dan saya beroperasi dengan kesadaran penuh bahwa mereka bisa mendefinisikan ulang barang saya kapan saja. Saya menganggap mereka cukup kompeten untuk mengetahui apa yang mereka lakukan pertama kali. Jika tidak, sepertinya saya tidak akan bekerja pada tim yang tidak menggunakan kontrol sumber.

  • Bagaimana Anda memutuskan apakah sekumpulan properti tertentu harusnya pribadi atau tidak? Jika secara default setiap bidang HARUS bersifat pribadi maka mengapa ada anggota data publik di kelas?

Dulu saya pikir itu konyol untuk menempatkan getter dan setters pada properti pribadi ketika Anda tidak benar-benar melakukan segala jenis validasi atau perlakuan khusus lainnya dari properti yang akan ditetapkan. Saya masih tidak berpikir itu selalu diperlukan, tetapi ketika Anda berurusan dengan skala besar, kompleksitas tinggi, tetapi yang paling penting banyak dev lainnya mengandalkan objek Anda berperilaku secara konsisten, dapat berguna untuk melakukan hal-hal dalam cara yang konsisten dan seragam. Ketika orang melihat metode dipanggil getThatdansetThat, mereka tahu persis apa niatnya, dan mereka dapat menulis objek mereka untuk berinteraksi dengan Anda dengan harapan bahwa mereka akan selalu mendapatkan tomat daripada tomahtos. Jika tidak, mereka tahu objek Anda memberi mereka sesuatu yang mungkin tidak seharusnya, yang berarti benda lain dapat melakukan sesuatu dengan data yang mungkin tidak seharusnya. Anda dapat mengendalikannya saat dibutuhkan.

Keuntungan besar lainnya adalah bahwa benda Anda lebih mudah diserahkan atau ditafsirkan nilai secara berbeda dari pengambil atau penyetel berdasarkan pada beberapa jenis konteks keadaan yang berbeda. Karena mereka mengakses barang-barang Anda dengan metode, jauh lebih mudah untuk mengubah cara objek Anda beroperasi nanti tanpa merusak kode lain yang bergantung padanya. Prinsip penting adalah bahwa hanya objek Anda yang benar-benar mengubah data yang Anda buat bertanggung jawab. Ini sangat penting untuk menjaga agar kode Anda tidak digabungkan secara longgar yang merupakan kemenangan besar dalam hal portabilitas dan kemudahan modifikasi.

  • Dalam keadaan apa suatu variabel harus dipublikasikan?

Dengan fungsi kelas satu (Anda dapat menggunakan fungsi sebagai argumen), saya tidak bisa memikirkan banyak alasan bagus selain tidak perlu untuk melakukannya pada proyek skala kecil. Tanpa itu, saya kira Anda mungkin memiliki anggota yang sedang diproses secara berat dan teratur oleh objek lain sampai-sampai tampaknya agak kasar untuk terus memanggil get dan menetapkan pada objek yang tidak benar-benar menyentuh data itu sendiri, tetapi di itu sendiri akan membuat saya bertanya-tanya mengapa objek bertanggung jawab atas data itu. Secara umum, saya cenderung ingin memeriksa kembali arsitektur saya untuk mencari kesalahan sebelum memutuskan properti data publik. IMO, tidak ada yang salah dengan bahasa yang memungkinkan Anda melakukan sesuatu yang biasanya merupakan ide yang buruk. Beberapa bahasa tidak setuju.

Erik Reppen
sumber
IMHO, tidak ada yang salah dengan memiliki kelas publik yang tujuan utamanya adalah mengekspos variabel publik. Memang, JVM memiliki sejumlah built-in kelas untuk tujuan itu: int[], double[],Object[] , dll Salah satu harus, bagaimanapun, sangat berhati-hati tentang bagaimana salah satu mengekspos contoh kelas tersebut. Arti void CopyLocationTo(Point p);[menerima Pointdari penelepon] lebih jelas daripada Point location(), karena tidak jelas apa efeknya Point pt = foo.location(); pt.x ++;pada lokasi foo.
supercat
2

Lihat posting saya ini untuk pertanyaan terkait pada SO .

Singkatnya adalah bahwa ruang lingkup variabel memungkinkan Anda untuk menunjukkan kepada konsumen kode Anda apa yang harus dan tidak boleh mereka lakukan. Variabel pribadi dapat menyimpan data yang telah "diperiksa" dengan menggunakan setter properti atau metode pemrosesan untuk memastikan seluruh objek dalam keadaan konsisten. Mengubah nilai variabel pribadi secara langsung dapat menyebabkan objek menjadi tidak konsisten. Dengan menjadikannya pribadi, seseorang harus bekerja sangat keras, dan memiliki izin runtime yang sangat tinggi, untuk mengubahnya.

Dengan demikian, pelingkupan anggota yang tepat adalah kunci dalam mendokumentasikan kode sendiri.

KeithS
sumber
2

Saya akan berbicara tentang nilai enkapsulasi dari perspektif yang berbeda menggunakan contoh nyata. Beberapa waktu yang lalu (awal 80-an) sebuah game ditulis untuk Radio Shack Color Computer yang disebut Dungeons of Daggorath. Beberapa tahun yang lalu, Richard Hunerlach memindahkannya dari daftar assembler kertas ke C / C ++ ( http://mspencer.net/daggorath/dodpcp.html ). Beberapa waktu kemudian, saya mendapatkan kode dan mulai memfaktorkannya kembali untuk memberikan enkapsulasi yang lebih baik, ( http://dbp-consulting.com/stuff/ ).

Kode sudah diperhitungkan menjadi objek yang berbeda untuk menangani penjadwalan, video, input pengguna, pembuatan ruang bawah tanah, monster, dll. Tapi Anda pasti bisa tahu bahwa itu porting dari assembler. Tugas terbesar saya adalah meningkatkan enkapsulasi. Maksud saya untuk mendapatkan bagian kode yang berbeda untuk mendapatkan hidung mereka keluar dari bisnis masing-masing. Ada banyak tempat misalnya, yang akan mengubah variabel video secara langsung untuk memiliki efek. Beberapa melakukannya dengan pengecekan kesalahan, beberapa tidak, beberapa memiliki ide yang agak berbeda tentang apa yang mengubah hal itu. Ada banyak duplikasi kode. Sebagai gantinya, bagian video perlu memiliki antarmuka untuk menyelesaikan tugas yang diinginkan, dan kode untuk melakukannya bisa saja di satu tempat, satu ide, satu tempat untuk debug. Hal semacam itu merajalela.

Ketika kode itu mulai diejek, bug yang bahkan tidak didiagnosis pun hilang. Kode menjadi lebih berkualitas. Setiap tugas menjadi tanggung jawab satu tempat dalam kode dan hanya ada satu tempat untuk memperbaikinya. (Saya masih menemukan lebih banyak setiap kali saya melewati kode.)

Segala sesuatu yang terlihat tentang kode Anda adalah antarmuka Anda. Apakah Anda bersungguh-sungguh atau tidak. Jika Anda membatasi visibilitas sebanyak mungkin maka Anda tidak akan tergoda untuk memasukkan kode di tempat yang salah nanti. Jelas bahwa bagian mana dari kode yang bertanggung jawab atas data mana. Itu membuat desain yang lebih baik, lebih bersih, lebih sederhana, dan lebih elegan.

Jika Anda membuat objek bertanggung jawab atas datanya sendiri, dan menyediakan antarmuka untuk semua orang yang membutuhkan sesuatu untuk terjadi, kode Anda menjadi BANYAK lebih sederhana. Itu hanya jatuh. Anda memiliki rutinitas sederhana kecil yang hanya melakukan satu hal. Lebih sedikit kompleksitas == lebih sedikit bug.

phorgan1
sumber
Keseimbangan yang sulit antara "kebebasan pengguna lib kami" dan "lebih sedikit masalah bagi kami". Saya mulai percaya bahwa enkapsulasi lebih baik dalam arti bahwa saya akan mencegah bug pada pengkodean saya sendiri, dan saya akan membantu pengguna akhir untuk mencegah bug juga. Tetapi kurangnya kebebasan mungkin hanya menyingkirkan mereka juga, mencari alternatif ... Mungkin pengkodean belum digunakan tetapi meramalkan fungsionalitas melalui metode publik dapat membantu menyeimbangkan itu, tetapi menuntut lebih banyak waktu.
Aquarius Power
Sayang sekali versi refactored tidak ada di github ....
jmoreno
2

Ini tidak ada hubungannya dengan kepercayaan atau ketakutan akan serangan, ini semata-mata tentang Enkapsulasi - tidak memaksa informasi yang tidak perlu pada pengguna kelas.

Pertimbangkan konstanta pribadi - mereka tidak boleh mengandung nilai-nilai rahasia (itu harus disimpan di tempat lain), mereka tidak dapat diubah, mereka tidak perlu diteruskan ke kelas Anda (jika tidak mereka harus menjadi publik). Satu-satunya penggunaan yang mungkin bagi mereka adalah sebagai konstanta di kelas OTHER. Tetapi jika Anda melakukan itu, kelas-kelas itu sekarang bergantung pada kelas Anda, untuk melakukan pekerjaan yang tidak terkait dengan kelas Anda. Jika Anda mengubah konstanta, kelas-kelas lain mungkin rusak. Itu buruk dari kedua belah pihak - sebagai penulis kelas Anda, Anda ingin kebebasan untuk berubah sebanyak mungkin, dan tidak ingin khawatir tentang hal-hal di luar kendali Anda. Seorang konsumen kelas Anda ingin dapat bergantung pada rincian kelas Anda yang terbuka, tanpa khawatir Anda mengubahnya dan melanggar kode mereka.

Seorang konsumen dari kelas Anda ingin mengetahui segala yang diperlukan untuk berinteraksi dengan kelas Anda, dan tidak ingin tahu apa pun tentang kelas Anda yang tidak mengubah cara mereka melakukannya: itu adalah hal-hal sepele yang tidak berguna. Jika Anda telah menggunakan bahasa dengan refleksi, seberapa sering Anda menggunakannya untuk belajar bukan bagaimana beberapa kelas melakukan sesuatu atau di mana ia melempar pengecualian secara tak terduga, tetapi hanya nama bidang dan metode pribadi? Saya bertaruh tidak pernah. Karena Anda tidak perlu menggunakan pengetahuan itu.

jmoreno
sumber
1

Konsep OOP memiliki inheritance memiliki salah satu fitur-fiturnya (Java atau C ++). Jadi jika kita akan mewarisi (artinya kita akan mengakses variabel dari kelas yang diwariskan), ada kemungkinan mempengaruhi variabel-variabel tersebut. Jadi kita harus memutuskan apakah variabel dapat diubah atau tidak.

Hanya untuk tujuan ini, kami menggunakan pengubah akses di OOP. Salah satu modifikasinya adalah privat yang artinya hanya dapat diakses oleh kelas itu. Kelas lain mana pun tidak dapat memengaruhi variabel-variabel tersebut.

Seperti yang kita ketahui, protected berarti dapat diakses oleh kelas yang akan diwarisi.

Mengapa ada konsep pengubah dalam OOP, adalah karena alasan ini (setiap kelas dapat mengakses variabel kelas lainnya menggunakan konsep OOP). Jika tidak ada konsep pengubah, itu berarti akan sulit saat mewarisi kelas atau menggunakan konsep OOP lainnya.

rajNaveen
sumber
1

Seperti yang dinyatakan oleh orang lain, variabel pribadi baik untuk menghindari kesalahan penggunaan yang mengarahkan objek ke status yang tidak konsisten dan sulit untuk melacak bug dan pengecualian yang tidak terduga.

Namun di sisi lain, yang paling sering diabaikan oleh yang lain adalah tentang bidang yang dilindungi.

Sub-kelas yang diperluas akan memiliki akses penuh ke bidang yang dilindungi, menjadikan objek itu rapuh seolah-olah bidang tersebut bersifat publik, tetapi kerapuhan itu terbatas pada kelas yang diperluas itu sendiri (kecuali jika itu membuka bidang tersebut lebih jauh lagi).

Jadi, bidang publik sulit untuk dianggap baik, dan sampai saat ini satu-satunya alasan untuk menggunakannya adalah untuk kelas yang digunakan sebagai parameter konfigurasi (kelas yang sangat sederhana dengan banyak bidang dan tanpa logika, sehingga kelas dilewatkan sebagai parameter saja untuk beberapa metode).

Namun di sisi lain, bidang pribadi menurunkan fleksibilitas kode Anda kepada pengguna lain.

Fleksibilitas vs Masalah, pro dan kontra:

Objek yang dipakai oleh kode Anda di kelas vanilla dengan bidang yang dilindungi aman dan merupakan tanggung jawab Anda sepenuhnya.

Di sisi lain, objek yang memperluas kelas Anda dengan bidang yang dilindungi, dipakai oleh pengguna kode Anda, adalah tanggung jawab mereka, bukan milik Anda.

Jadi, bidang / metode yang tidak terdokumentasi dengan baik, atau jika pengguna tidak benar-benar memahami bagaimana bidang dan metode tersebut harus digunakan, memiliki peluang bagus untuk menyebabkan masalah yang tidak perlu bagi diri mereka dan Anda.

Di sisi lain, menjadikan sebagian besar hal pribadi akan menurunkan fleksibilitas pengguna, dan bahkan mungkin menyisihkan mereka mencari alternatif yang dikelola, karena mereka mungkin tidak ingin membuat dan memelihara garpu hanya untuk membuat hal-hal terjadi sesuai keinginan mereka.

Jadi, keseimbangan yang baik antara pribadi, dilindungi, dan publik adalah yang terpenting.

Sekarang, untuk memutuskan antara pribadi dan dilindungi adalah masalah sebenarnya.

Kapan menggunakan dilindungi?

Setiap kali Anda memahami suatu bidang bisa sangat fleksibel, itu harus dikodekan sebagai dilindungi. Fleksibilitas itu adalah: dari menjadi nol (di mana nol selalu diperiksa dan dikenali sebagai status yang valid tanpa melempar pengecualian), hingga memiliki kendala sebelum digunakan oleh mantan kelas Anda. > = 0, <100 dll, dan secara otomatis diperbaiki untuk nilai over / under-flowed, melemparkan paling banyak pesan peringatan.

Jadi, untuk bidang yang dilindungi tersebut, Anda dapat membuat pengambil dan hanya menggunakannya (alih-alih langsung menggunakan variabel bidang), sementara pengguna lain mungkin tidak menggunakannya, jika mereka menginginkan lebih banyak fleksibilitas untuk kode spesifik mereka, dalam contoh saya bisa seperti : jika mereka ingin nilai negatif berfungsi dengan baik di kelas mereka.

Kekuatan Aquarius
sumber
-1

imo @tdammers tidak benar dan sebenarnya menyesatkan.

Variabel pribadi ada untuk menyembunyikan detail implementasi. Kelas Anda Amungkin menggunakan a arrayuntuk menyimpan skor. Besok Anda mungkin ingin menggunakan treeatau priority queuesebagai gantinya. Semua pengguna kelas Anda membutuhkan cara untuk memasukkan skor dan nama addScore()dan cara untuk mencari tahu siapa yang 10 besar getTop(n).

Mereka tidak perlu mengakses struktur data yang mendasarinya. Kedengarannya bagus? Nah, ada beberapa peringatan.

Anda seharusnya tidak menyimpan banyak status, sebagian besar tidak diperlukan. Menyimpan status akan menyulitkan kode Anda bahkan ketika "dipisahkan" ke kelas tertentu. Pikirkan tentang hal itu, variabel pribadi itu mungkin berubah karena objek lain disebut metode kelas itu. Anda masih perlu mencari tahu kapan dan di mana metode itu dipanggil dan metode publik itu dapat dipanggil di mana saja secara teoritis.

Hal terbaik yang dapat Anda lakukan adalah membatasi jumlah status yang berisi program Anda dan menggunakan fungsi murni bila memungkinkan.

serigala
sumber
-1
  • Mengakses variabel berarti mengakses nilainya ketika program berjalan, membuat variabel menjadi pribadi yang dilindungi nilainya ketika kode berjalan.
  • Maksud dari apa yang disebut "data hiding" adalah untuk menyembunyikan data internal dari kelas lain yang menggunakan kelas. Kelas-kelas lain hanya boleh mengakses perilaku dengan memanggil metode di kelas, bukan dengan mengubah nilai variabel secara langsung.
  • Dengan menjadikan variabel sebagai anggota data pribadi, Anda dapat lebih mudah memastikan bahwa nilainya tidak pernah diubah atau diubah. Di sisi lain, jika variabel bersifat publik, kelas lain dapat memodifikasi atau mengubah nilai yang dapat menyebabkan bagian lain dari kode mogok.
Purvi Barot
sumber
1
ini tampaknya tidak menawarkan sesuatu yang substansial atas poin yang dibuat dan dijelaskan dalam 17 jawaban sebelumnya
nyamuk
-4

Anda harus terlebih dahulu memahami konsep pemrograman berorientasi objek. Ini memiliki abstraksi, enkapsulasi dll.

Abstraksi - Anda mendapatkan ide tentang logika tanpa perlu tahu detail pelaksanaannya.

Enkapsulasi - Anda tidak dapat melihat garis bawah implementasi objek. Hanya Anda yang dapat melihat antarmuka publik objek.

Sekarang dalam implementasi spesifik dengan salah satu program berorientasi objek seperti C #, Java, C ++ Anda dapat mengimplementasikan konsep-konsep ini.

pribadi - Implementasi yang harus disembunyikan dari dunia luar. Sehingga Anda bisa mengubahnya dan pengguna kelas Anda tidak terpengaruh.

publik - Ini adalah antarmuka tempat seseorang dapat menggunakan objek Anda.

DeveloperArnab
sumber
1
dilindungi - dapat diakses langsung oleh sub-kelas (ekstender) (java).
Aquarius Power