Apakah bidang publik Jawa hanya cacat desain sejarah yang tragis pada titik ini? [Tutup]


17

Tampaknya menjadi ortodoksi Jawa pada titik ini bahwa seseorang pada dasarnya tidak boleh menggunakan bidang publik untuk keadaan objek. (Saya tidak harus setuju, tapi itu tidak relevan dengan pertanyaan saya.) Mengingat itu, apakah benar untuk mengatakan bahwa dari tempat kita hari ini, jelas bahwa bidang publik Jawa adalah kesalahan / cacat dari desain bahasa? Atau adakah argumen rasional bahwa itu adalah bagian yang berguna dan penting dari bahasa tersebut, bahkan hari ini?

Terima kasih!

Pembaruan: Saya tahu tentang pendekatan yang lebih elegan, seperti dalam C #, Python, Groovy, dll. Saya tidak secara langsung mencari contoh-contoh itu. Saya benar-benar hanya ingin tahu apakah masih ada seseorang di dalam bunker, bergumam tentang betapa indahnya bidang publik, dan bagaimana massa semua hanyalah domba, dll.

Pembaruan 2: Bidang publik final yang jelas statis adalah cara standar untuk membuat konstanta publik. Saya merujuk lebih banyak menggunakan bidang publik untuk status objek (bahkan kondisi tidak berubah). Saya berpikir bahwa ini kelihatannya seperti cacat desain yang harus digunakan bidang publik untuk konstanta, tetapi tidak untuk negara ... aturan bahasa harus ditegakkan secara alami, dengan sintaks, bukan oleh pedoman.


2
Apa dasar Anda bahwa mereka memang cacat?
Aaron McIver

1
Apakah ada cara berbeda untuk membuat ekspresi konstan simbolis di Jawa sekarang?
Edward Strange

@ Harun Saya tidak menyatakan bahwa mereka cacat, saya menyatakan bahwa saya menganggapnya ortodoksi pada titik ini bahwa seseorang tidak boleh menggunakan bidang publik. Persepsi itu mungkin salah, tetapi memang itulah yang saya rasakan.
Avi Flax

@Crazy Eddie Saya lupa tentang penggunaan itu, saya lebih memikirkan penggunaan yang lebih umum dari field, state. Saya akan mengedit pertanyaan.
Avi Flax

Jawaban:


14

Saya suka mereka, selama bidangnya final dan hanya digunakan secara internal dalam aplikasi, tidak terpapar dalam API untuk aplikasi lain. Ini membuat kode Anda lebih pendek dan lebih mudah dibaca.

Anda tidak boleh mengekspos bidang publik dalam API karena dengan mengekspos bidang publik, Anda juga mengekspos implementasinya. Jika Anda mengeksposnya sebagai getXXX()metode, Anda bisa mengubah implementasi tanpa mengubah antarmuka API. Misalnya Anda bisa mengubah dan mendapatkan nilai dari layanan jarak jauh, tetapi aplikasi yang menggunakan API tidak perlu mengetahui hal ini.

Ini adalah desain yang layak untuk public finalbidang dalam kelas tidak berubah .

Dari Java Efektif :

Butir 14: Di kelas publik, gunakan metode accessor, bukan bidang publik

... jika kelas adalah paket-privat atau kelas bersarang pribadi, tidak ada yang salah dengan mengekspos bidang datanya. Pendekatan ini menghasilkan lebih sedikit kekacauan daripada pendekatan metode aksesor.

Meskipun tidak pernah merupakan ide bagus bagi kelas publik untuk mengekspos bidang secara langsung, itu tidak terlalu berbahaya jika bidang tersebut tidak dapat diubah.

Lihat juga. Mengapa saya tidak harus menggunakan POJO yang tidak bisa diubah sebagai ganti JavaBeans?


Hanya ingin tahu, apa alasan Anda untuk tidak mengeksposnya di API?
Steven Jeuris

2
@ Sebelas: Karena dengan mengekspos bidang publik, Anda juga mengekspos implementasinya. Jika Anda mengeksposnya sebagaigetXXX() metode, Anda bisa mengubah implementasi tanpa mengubah antarmuka API. Misalnya Anda bisa mengubah dan mendapatkan nilai dari layanan jarak jauh, tetapi aplikasi yang menggunakan API tidak perlu mengetahui hal ini.
Jonas

@Jonas: Mereka biasanya bukan kandidat untuk konstanta.
Steven Jeuris

@ Seven: Saya tidak berbicara tentang konstanta di tempat pertama tetapi bidang akhir publik di kelas abadi . Misalnya, lihat Mengapa saya tidak harus menggunakan POJO yang tidak dapat diubah alih-alih JavaBeans?
Jonas

@Jonas: Itu kasus penggunaan yang bagus juga! Mungkin sedikit membantu untuk memperbarui jawaban Anda untuk memperjelas.
Steven Jeuris

9

Penggunaan pasangan metode get / set adalah cacat desain sejarah yang tragis. Saya tidak bisa memikirkan bahasa lain yang mengimplementasikan properti secara verbal dan tidak efisien.


1
Meskipun benar, ini agak tangensial ke titik pertanyaan, yang (pada dasarnya) yang diberikan pilihan antara metode set / get dan bidang publik, apakah ada alasan yang baik untuk memilih bidang dalam beberapa situasi? Bahwa bahasa lain menawarkan solusi yang lebih baik untuk masalah itu bagi saya tampaknya tidak relevan.
Jules

5

Saya pikir bidang publik baik-baik saja untuk kelas yang pada dasarnya adalah tipe nilai seperti bilangan kompleks atau titik, di mana kelas melakukan sedikit lebih banyak daripada tipe kelompok primitif bersama-sama seperti struct C-style dan mungkin mendefinisikan beberapa operator.


2
java.awt.Pointdan teman-teman sedikit mimpi buruk.
Tom Hawtin - tackline

@ TomHawtin-tackline: Masalahnya Pointadalah tidak jelas apakah variabel tipe Pointseharusnya merangkum sebuah lokasi, atau seharusnya merangkum identitas entitas dengan lokasi yang dapat berubah. Secara konseptual, saya akan menganggap kode yang melewati Pointmenjadi seperti kode yang melewati array.
supercat

Jadi jika saya mendapatkan Pointdan memodifikasinya, saya harus mengharapkan objek yang dimaksud untuk memperbarui secara bersih di layar? Tidak, masalahnya Pointadalah ia bisa berubah. Kami memiliki String/ StringBuffertetapi ide itu tampaknya tidak berhasil. / Melewati array di sekitar memang memiliki masalah yang sama.
Tom Hawtin - tackline

5

Untuk mendefinisikan konstanta publik masih bermanfaat. Misalnya

int final statis publik DAYS_IN_WEEK = 7;

Namun, tetap lebih suka enum jika memungkinkan. Misalnya

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, 
    THURSDAY, FRIDAY, SATURDAY 
}

Untuk mensimulasikan kelas struct sederhana itu juga berguna. Tidak ada alasan untuk membuat pengambil dan penyetel untuk setiap bidang, saat semuanya bersifat publik.

class Point
{
    public int x, y;
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

Tetapi sekali lagi, banyak yang akan berpendapat struct tidak memiliki tempat dalam bahasa seperti Java ...

1
@delnan: Mereka hampir sama dengan JavaBeans, tetapi JavaBeans jauh lebih verbose dan bukan threadsafe. Lihat Mengapa saya tidak harus menggunakan POJO yang tidak dapat berubah alih-alih JavaBeans?
Jonas

Beberapa pengamatan khusus Android: Enum lebih lambat untuk dievaluasi daripada int dan harus dihindari. Juga, bidang yang sering diakses oleh setter dan getter di loop ketat juga bisa mendapat manfaat dari menjadi publik.
Nailer

2

Sebelum IDE menyebar, menjadikan semua bidang Anda publik adalah alat yang ampuh untuk membuat prototipe / bukti konsep dengan cepat.

Saat ini ada sangat sedikit alasan untuk menggunakannya, ketika Anda dapat menghasilkan pasangan pengambil / penyetel dengan klik mouse.


4
Tetapi 10 public finalbidang lebih mudah dibaca daripada 10 getXXX()metode.
Jonas

1
@ Jonas Ya, tapi kita tidak berbicara tentang bidang terakhir di sini. Jika bidang final publik Anda juga statis, itu adalah konstanta, dan constkata kunci akan cukup, jika tidak statis, itu adalah pelanggaran serius enkapsulasi.
biziclop

3
@biziclop menurut Wikipedia : "walaupun dicadangkan sebagai kata kunci di Jawa, const tidak digunakan dan tidak memiliki fungsi"
Avi Flax

@ Avi Flax Ya, tapi itu bisa digunakan untuk menandai konstanta, sehingga menghilangkan kebutuhan untuk menyatakan konstanta sebagai bidang publik.
biziclop

2
Mengasumsikan pasangan pengambil / penyetel sama sekali sesuai, yaitu. Seringkali tidak.
David Thornley

2

Ini subjektif, tetapi pendapat saya adalah bahwa seluruh gagasan publik / pribadi sudah usang dan mundur.

Dalam python tidak ada publik / pribadi; semuanya pada dasarnya bersifat publik. Belum menyebabkan banyak masalah.

Di Jawa Anda cenderung membuat getter / setters tanpa tujuan untuk setiap bidang untuk menghindari dosa menandai mereka "publik". (IMHO jika Anda menemukan diri Anda melakukan itu, Anda harus menandai mereka publik).


Python memang memungkinkan Anda untuk menandai hal-hal sebagai pribadi dengan mengawali nama dengan __. Ini bukan 100% pribadi, karena masih ada cara untuk mengakses variabel dan metode tersebut, tetapi kemudian di C # Anda dapat melakukan hal serupa dengan refleksi.
Adam Lear
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.