Tempat saya bekerja, saya melihat banyak kelas yang melakukan hal-hal seperti ini:
public class ClassThatCallsItsOwnGettersAndSetters {
private String field;
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
public void methodWithLogic() {
setField("value");
//do stuff
String localField = getField();
//do stuff with "localField"
}
}
Jika saya menulis ini dari awal, saya akan menulis methodWithLogic()
seperti ini sebagai gantinya:
public class ClassThatUsesItsOwnFields {
private String field;
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
public void methodWithLogic() {
field = "value";
//do stuff
//do stuff with "field"
}
}
Saya merasa bahwa ketika kelas memanggil getter dan setter sendiri, itu membuat kode lebih sulit untuk dibaca. Bagi saya hampir menyiratkan bahwa logika kompleks terjadi dalam pemanggilan metode meskipun dalam kasus kami hampir tidak pernah ada. Ketika saya sedang men-debug beberapa kode yang tidak dikenal, siapa yang mengatakan bahwa bug tersebut tidak menimbulkan efek samping dalam metode itu? Dengan kata lain, itu membuat saya melakukan banyak perjalanan samping dalam perjalanan memahami kode.
Apakah ada manfaat untuk metode pertama? Apakah metode pertama sebenarnya lebih baik?
sumber
Jawaban:
Saya tidak akan mengatakan mana yang lebih baik atau lebih buruk, karena itu sebagian tergantung pada situasi Anda (menurut saya). Tetapi pertimbangkan bahwa getter dan setter Anda dapat mengubah implementasi nanti, dan melewati mereka akan melewati logika itu.
Misalnya, apa yang terjadi jika Anda menambahkan bendera "kotor" ke beberapa bidang setter nanti? Dengan memanggil setter Anda di kode internal Anda, Anda akan menetapkan bendera kotor tanpa mengubah kode lainnya. Dalam banyak situasi ini akan menjadi hal yang baik.
sumber
setField()
dari awal, Anda baru saja memperkenalkan bug.Memanggil setter secara langsung bukanlah masalah. Pertanyaannya seharusnya: Mengapa kode kita memiliki seter di mana-mana?
Kelas yang bisa berubah adalah permainan yang berbahaya, terutama di mana kelas itu sendiri mengelola negaranya sendiri. Pertimbangkan berapa banyak pemukim yang benar-benar perlu ada. Berapa banyak yang bisa diatur dalam konstruktor dan kemudian menjadi dienkapsulasi seluruhnya oleh kelas itu sendiri?
Jika bidang harus diselesaikan secara eksternal maka tanyakan pada diri Anda apakah metode dengan logika harus ada. Apakah kelas Anda sendiri benar-benar hanya kelas data / negara bagian? Apakah kelas ini memiliki lebih dari satu tanggung jawab?
Jangan salah paham, akan ada kasus di mana ini baik-baik saja. Saya tidak mengatakan bahwa Anda harus menghilangkan setter pada kelas dengan logika sepenuhnya. Tapi ini harus menjadi pengecualian, bukan aturannya. Dan, dalam beberapa kasus itu, harus jelas mana yang dapat diakses secara langsung.
sumber
Ya, metode kelas Anda harus memanggil getter dan setter. Inti dari penulisan getter dan setter adalah pemeriksaan di masa depan. Anda bisa membuat setiap properti menjadi bidang dan langsung mengekspos data ke pengguna kelas. Alasan Anda membuat getter dan setter belum tentu karena ada logika kompleks sekarang tetapi agar antarmuka tidak rusak di masa depan jika Anda harus menambahkannya.
sumber
someField=newValue; refresh();
Jika metode memungkinkan beberapa bidang diatur, memanggil setter untuk menulis bidang-bidang itu akan menyebabkan operasi "penyegaran" yang berlebihan. Menulis semua bidang dan kemudian meneleponrefresh()
sekali dapat menghasilkan operasi yang lebih efisien dan tampak lebih halus.Untuk menjawab pertanyaan Anda dalam satu kata, ya.
Memiliki panggilan kelas getter dan setter sendiri menambahkan ekstensibilitas dan menyediakan basis yang lebih baik untuk kode masa depan.
Katakan Anda memiliki sesuatu seperti ini:
Memanggil setter untuk tahun dan membuat saat ini mungkin tidak menambahkan fungsionalitas apa pun, tetapi bagaimana jika Anda ingin menambahkan sesuatu seperti validasi input ke setter?
sumber
Satu hal yang belum disebutkan adalah bahwa pengambil dan penyetel (karena semua metode) adalah virtual di Jawa. Ini menambahkan fitur lain untuk selalu menggunakannya dalam kode Anda. Pengguna lain dapat memperluas kelas Anda, menimpa getter dan setter Anda. Kelas dasar Anda kemudian akan menggunakan data subkelas alih-alih miliknya. Dalam bahasa di mana Anda secara eksplisit menandai fungsi virtual, ini jauh lebih praktis karena Anda dapat memprediksi dan mendeklarasikan fungsi mana yang bisa dilakukan. Di Jawa, ini adalah sesuatu yang Anda harus selalu waspadai. Jika perilaku yang diinginkan maka menggunakannya dalam kode Anda adalah hal yang baik, jika tidak, tidak begitu banyak.
sumber
Jika Anda mencoba untuk mencapai sesuatu yang disediakan oleh antarmuka publik, maka gunakan getter / setter.
Namun, sebagai pemilik / pengembang kelas, Anda diizinkan untuk mengakses bagian pribadi dari kode Anda (dari dalam kelas tentu saja), tetapi Anda juga bertanggung jawab untuk mengurangi bahaya.
Jadi mungkin Anda memiliki pengambil yang beralih pada beberapa daftar internal, dan Anda ingin mendapatkan nilai saat ini tanpa menambah iterator. Dalam hal ini, gunakan variabel pribadi.
sumber
Iya. Getters dan setters mewakili status, jadi balikkan pertanyaan ini - apakah Anda ingin melacak beberapa cara untuk mengubah status objek dengan cara yang sama kecuali Anda harus?
Semakin sedikit hal yang harus Anda perhatikan, semakin baik - inilah sebabnya objek yang tidak dapat diubah lebih mudah ditangani.
Pertimbangkan, tidak ada yang mencegah Anda memiliki bidang publik dan pengambil / penyetel publik - tetapi apa yang akan Anda peroleh?
Kadang-kadang mungkin diinginkan atau bahkan perlu untuk secara langsung mengakses lapangan karena satu atau beberapa alasan, Anda tidak boleh menghindarinya jika itu terjadi. Tetapi Anda harus benar-benar hanya melakukannya jika ada manfaat yang pasti untuk melakukannya.
sumber
Kedua metode memiliki kasus penggunaannya. Karena setter publik menjaga nilai bidang (dan / atau nilai terikat) konsisten, Anda harus menggunakan setter saat logika metode Anda tidak mengganggu logika konsistensi ini. Jika Anda hanya mengatur "properti" Anda, gunakan setter. Di sisi lain, ada situasi, di mana Anda memerlukan akses langsung ke beberapa bidang, misalnya operasi massal dengan setter berat, atau operasi di mana konsep setter terlalu sederhana.
Adalah tanggung jawab Anda untuk menjaga segala sesuatu tetap konsisten. Setter melakukan ini menurut definisi, tetapi tidak dapat mencakup kasus yang kompleks.
sumber
Saya akan mengatakan Tidak ..
Jika getter / setter Anda hanya mendapatkan dan mengatur (tidak ada inisialisasi malas, tidak ada pemeriksaan, dll) maka gunakan saja variabel Anda. Jika di masa depan Anda mengubah getter / setter Anda, Anda dapat dengan sangat baik mengubah
methodWithLogic()
(karena kelas Anda yang berubah) dan Anda dapat memanggil pengambil / setter alih-alih penugasan langsung. Anda dapat mendokumentasikan panggilan ini untuk pengambil / penyetel (karena akan aneh untuk memanggil pengambil / penyetel ketika sisa kode kelas Anda langsung menggunakan variabel).JVM akan inline sering panggilan ke getter / setter. Jadi, ini bukan masalah kinerja. Keuntungan menggunakan variabel adalah keterbacaan dan IMHO, saya akan melakukannya.
Semoga ini membantu..
sumber