Saya membaca halaman ini , tentang kapan getter / setter dibenarkan, dan OP memberikan contoh kode berikut:
class Fridge
{
int cheese;
void set_cheese(int _cheese) { cheese = _cheese; }
int get_cheese() { return cheese; }
}
void go_shopping(Fridge fridge)
{
fridge.set_cheese(fridge.get_cheese() + 5);
}
The diterima Jawaban negara:
By the way, dalam contoh Anda, saya akan memberikan kelas
Fridge
yangputCheese()
dantakeCheese()
metode, bukanget_cheese()
danset_cheese()
. Maka Anda masih akan memiliki enkapsulasi.
Bagaimana enkapsulasi dipertahankan dengan mengganti nama dari get / set ke putCheese()
/ takeCheese()
Anda jelas mendapatkan / menetapkan nilai, jadi mengapa tidak meninggalkannya sebagai get / set?
Dalam jawaban yang sama juga disebutkan:
Memiliki getter dan setter tidak dengan sendirinya merusak enkapsulasi. Apa yang memecahkan enkapsulasi secara otomatis menambahkan pengambil dan penyetel untuk setiap anggota data (setiap bidang, dalam istilah java), tanpa memikirkannya.
Dalam hal ini, kami hanya memiliki satu variabel,, cheese
dan Anda mungkin ingin mengambil dan mengembalikan keju ke lemari es, sehingga pasangan get / set dalam kasus ini dibenarkan.
sumber
putCheese
akan menambahkan keju ke lemari es, dantakeCheese
akan menghapusnya - ini adalah abstraksi berorientasi domain (tingkat lebih tinggi), bukan pengambil & setter bidang objek (yang merupakan abstraksi pemrograman komputer level rendah).Jawaban:
Saya pikir kamu melewatkan intinya. Itu tidak mengatakan Anda harus mengganti nama setter dan pengambil, tetapi memiliki metode yang menambah dan menghapus item dari lemari es. yaitu
Sekarang variabel pribadi dienkapsulasi. Saya tidak bisa hanya mengaturnya untuk apa pun yang saya inginkan, saya hanya bisa menambah dan menghapus irisan keju dari kulkas menggunakan metode, yang pada gilirannya memastikan bahwa aturan logika bisnis keju apa pun yang saya inginkan diterapkan.
sumber
setCheese()
memiliki logika yang sama di setter. Bagi saya, Anda berusaha menyembunyikan fakta bahwa Anda menggunakan setter dengan mengganti nama metode, tetapi jelas pengambil / pengaturan sesuatu.AddCheese(Integer.MAX_VALUE)
seharusnya gagal, tetapi tidak akan.Getters dan setters memecah enkapsulasi setiap saat , menurut definisi. Yang mungkin diperdebatkan adalah bahwa kadang-kadang kita perlu melakukan itu. Dengan hal itu, inilah jawaban saya:
Perbedaannya adalah dalam semantik, yaitu makna dari apa yang Anda tulis. Enkapsulasi tidak hanya tentang melindungi, tetapi menyembunyikan kondisi internal. Keadaan internal seharusnya tidak diketahui di luar, sebaliknya objek diharapkan untuk menawarkan metode yang relevan dengan bisnis (kadang-kadang disebut sebagai "perilaku") untuk memanipulasi / menggunakan keadaan itu.
Jadi
get
danset
merupakan istilah teknis dan tampaknya tidak ada hubungannya dengan domain "kulkas", sementaraput
dantake
mungkin benar-benar masuk akal.Namun , apakah
put
atautake
membuat yang sebenarnya akal masih tergantung pada persyaratan dan tidak dapat secara obyektif dinilai. Lihat poin selanjutnya:Itu tidak dapat ditentukan secara objektif tanpa lebih banyak konteks. Contoh Anda berisi
go_shopping()
metode di tempat lain. Jika itu untuk apaFridge
, daripada tidak perluget
atauset
, apa yang dibutuhkanFridge.go_shopping()
. Dengan cara ini Anda memiliki metode yang berasal dari persyaratan, semua "data" yang dibutuhkan adalah lokal dan Anda memiliki perilaku aktual, bukan hanya struktur data terselubung.Ingat, Anda tidak membangun generik, dapat digunakan kembali
Fridge
. Anda sedang membangunFridge
untuk kebutuhan Anda saja. Upaya apa pun yang dihabiskan untuk membuatnya lebih dari yang seharusnya sebenarnya sia-sia.sumber
Getters and setters break encapsulation every single time
- Itu agak terlalu kuat untuk seleraku. Metode (termasuk getter dan setter) memiliki tujuan yang sama seperti gerbang di konser: mereka memungkinkan masuk dan keluar teratur dari tempat tersebut.public int getFoo()
, hampir tidak mungkin, dalam praktiknya, untuk berubah ke tipe lain.Hampir semua ini menunjukkan kesalahpahaman mendasar tentang enkapsulasi, dan bagaimana itu berlaku.
Respons awal yang Anda hancurkan adalah enkapsulasi. Aplikasi Anda mungkin memiliki kebutuhan untuk hanya mengatur nilai keju di lemari es daripada kenaikan / penurunan atau menambah / menghapus. Selain itu, ini bukan semantik, tidak peduli bagaimana Anda menyebutnya, jika Anda memiliki kebutuhan untuk mengakses dan / atau mengubah atribut Anda tidak merusak enkapsulasi dengan menyediakannya. Akhirnya, enkapsulasi tidak benar-benar tentang "bersembunyi", ini tentang mengendalikan akses ke negara dan nilai-nilai yang tidak perlu dipublikasikan atau dimanipulasi di luar kelas, sementara memberikannya kepada orang-orang yang seharusnya dan melakukan tugas yang disediakan secara internal.
Seorang pengambil atau penyetel tidak memecah enkapsulasi ketika ada kebutuhan sah untuk mendapatkan atau menetapkan nilai. Inilah sebabnya mengapa metode dapat dipublikasikan.
Enkapsulasi adalah tentang menyimpan data dan metode yang memodifikasi data secara langsung bersama di satu tempat logis, kelas.
Dalam kasus khusus ini, jelas ada kebutuhan untuk mengubah nilai keju dalam aplikasi. Terlepas dari bagaimana hal ini dilakukan, melalui get / set atau tambah / hapus, selama metode dienkapsulasi di kelas Anda mengikuti gaya berorientasi objek.
Untuk klarifikasi, saya akan memberikan contoh bagaimana enkapsulasi dipecah dengan menyediakan akses terlepas dari nama metode atau eksekusi logis.
Katakanlah lemari es Anda memiliki "masa hidup", hanya beberapa kutu sebelum lemari es tidak lagi beroperasi (demi argumen, kulkas tidak dapat diperbaiki). Secara logis tidak ada cara pengguna (atau sisa aplikasi Anda) harus dapat mengubah nilai ini. Itu harus pribadi. Itu hanya akan terlihat melalui mengatakan atribut publik yang berbeda yang dikenal sebagai "isWorking". Ketika masa hidup berakhir, secara internal set kulkas bekerja dengan palsu.
Pelaksanaan menghitung mundur seumur hidup dan membalik saklar isWorking semua internal ke lemari es, tidak ada yang di luar bisa / harus dapat mempengaruhi proses. isWorking seharusnya hanya terlihat, sehingga pengambil tidak merusak enkapsulasi. Namun menambahkan pengakses untuk elemen proses seumur hidup akan merusak enkapsulasi Anda.
Seperti kebanyakan hal, definisi enkapsulasi tidak literal, itu relatif. Apakah Anda dapat melihat X di luar kelas? Apakah Anda dapat mengubah Y? Apakah semua yang berlaku untuk objek Anda di sini di kelas ini atau apakah fungsinya tersebar di beberapa kelas?
sumber
Bukan hanya mengubah nama metode. Dua metode berfungsi secara berbeda.
(Bayangkan ini di pikiran Anda)
get_cheese dan set_cheese memperlihatkan keju. putCheese () dan takeCheese () menjaga keju tetap tersembunyi dan mengurusnya serta memberi pengguna cara untuk menanganinya. Pengamat tidak melihat keju, ia hanya melihat dua metode memanipulasinya.
sumber