Mengapa variabel statis dianggap jahat?

635

Saya seorang programmer Java yang baru dalam dunia korporat. Baru-baru ini saya telah mengembangkan aplikasi menggunakan Groovy dan Java. Semua melalui kode yang saya tulis menggunakan statika yang cukup baik. Saya diminta oleh banyak teknis senior untuk mengurangi jumlah statika yang digunakan. Saya sudah googled tentang hal yang sama, dan saya menemukan bahwa banyak programmer cukup menentang menggunakan variabel statis.

Saya menemukan variabel statis lebih nyaman digunakan. Dan saya menganggap bahwa mereka juga efisien (tolong perbaiki saya jika saya salah), karena jika saya harus membuat 10.000 panggilan ke suatu fungsi dalam suatu kelas, saya akan senang untuk membuat metode ini statis dan langsung menggunakan metode Class.methodCall()itu daripada menggunakannya mengacaukan memori dengan 10.000 instance kelas, kan?

Selain itu statika mengurangi saling ketergantungan pada bagian lain dari kode. Mereka dapat bertindak sebagai pemegang negara yang sempurna. Menambah ini saya menemukan bahwa statika banyak diimplementasikan dalam beberapa bahasa seperti Smalltalk dan Scala . Jadi mengapa penindasan terhadap statika ini lazim di kalangan pemrogram (terutama di dunia Jawa)?

PS: tolong perbaiki saya kalau anggapan saya tentang statika salah.

Vamsi Emani
sumber
43
Hanya demi mengatakan, tidak ada variabel statis atau metode pada Smalltalk atau Scala, tepatnya karena metode dan variabel statis bertentangan dengan prinsip-prinsip OOP.
Maurício Linhares
87
Setidaknya satu pernyataan yang Anda buat agak aneh: "statika mengurangi saling ketergantungan pada bagian lain dari kode". Secara umum mereka memperketat ketergantungan. Kode tempat panggilan dilakukan terikat sangat erat dengan kode yang dipanggil. Tidak ada abstraksi di antara, ketergantungan langsung.
Arne Deutsch
11
Pertanyaan bagus ... lebih lanjut tentang seorang Programmer. Pertanyaan SE bukan?
WernerCD
26
Paragraf kedua Anda adalah tentang subjek yang sama sekali berbeda, yaitu metode statis .
Paul
8
Pemrograman fungsional juga disukai negara global. Jika Anda pernah (dan Anda harus ) masuk ke FP suatu hari, bersiaplah untuk membuang gagasan tentang negara global.
new123456

Jawaban:

689

Variabel statis mewakili keadaan global. Itu sulit untuk dipikirkan dan sulit untuk diuji: jika saya membuat instance baru dari sebuah objek, saya bisa beralasan tentang status barunya dalam pengujian. Jika saya menggunakan kode yang menggunakan variabel statis, bisa dalam keadaan apa pun - dan apa pun bisa memodifikasinya.

Saya bisa berjalan cukup lama, tetapi konsep yang lebih besar untuk dipikirkan adalah semakin sempit ruang lingkup sesuatu, semakin mudah untuk dipikirkan. Kami pandai memikirkan hal-hal kecil, tetapi sulit untuk beralasan tentang keadaan sistem sejuta baris jika tidak ada modularitas. Omong-omong, ini berlaku untuk segala macam hal - bukan hanya variabel statis.

Jon Skeet
sumber
57
Akhir-akhir ini sepertinya menjadi argumen, apakah kode diuji atau tidak. Itu alasan yang agak cacat. Argumennya harus 'desain yang baik', dan biasanya desain yang baik dapat diuji. Tetapi tidak sebaliknya: "Saya tidak bisa mengujinya karena itu pasti desain yang buruk." Jangan salah paham, saya setuju dengan posting Anda secara umum.
M Platvoet
144
@ M Platvoet: Saya akan mengatakan bahwa diberi pilihan antara dua desain yang sama-sama valid, yang diuji lebih unggul. Menjadi teruji tentu tidak sama dengan dirancang dengan baik, tetapi saya jarang menemukan desain yang baik, dan saya pikir mereka cukup langka sehingga saya tidak punya masalah dalam membuat testabilitas sebagai tujuan umum yang berkontribusi indikator menuju desain yang baik.
Jon Skeet
9
@M Platvoet - Testabilitas memengaruhi kemampuan pemeliharaan dan keandalan, dan saya akan mempertimbangkan faktor-faktor utama dalam kualitas desain. Mereka bukan satu-satunya faktor, tentu saja, tetapi IMHO biaya dari setiap kode yang diberikan adalah kombinasi dari siklus mesin, siklus pengembang, dan siklus pengguna. Testabilitas mencapai dua dari tiga.
Justin Morgan
5
@M Platvoet - Testability juga cenderung memengaruhi reusability, karena kelas yang dipisahkan secara umum lebih mudah untuk digunakan kembali.
TrueWill
13
M Platvoet - Saya tidak setuju dengan komentar pertama Anda di sini. Saya pikir jika sesuatu tidak dapat diuji, maka itu desain yang buruk; karena jika saya tidak bisa mengujinya, saya tidak tahu itu berfungsi. Apakah Anda akan membeli mobil jika wiraniaga mengatakan kepada Anda "Desain model ini mencegahnya dari diuji, jadi saya tidak tahu apakah itu benar-benar berjalan"? Testabilitas sangat penting untuk perangkat lunak (dan juga mobil), sehingga desain yang kompeten MENUNTUT sehingga disertakan.
Dawood ibn Kareem
277

Ini tidak terlalu berorientasi objek: Salah satu alasan statika dapat dianggap "jahat" oleh beberapa orang adalah mereka bertentangan dengan paradigma berorientasi objek . Secara khusus, itu melanggar prinsip bahwa data dienkapsulasi dalam objek (yang dapat diperluas, menyembunyikan informasi, dll). Statika, dalam cara Anda menggambarkan menggunakannya, pada dasarnya menggunakannya sebagai variabel global untuk menghindari berurusan dengan masalah seperti ruang lingkup. Namun, variabel global adalah salah satu karakteristik mendefinisikan paradigma pemrograman prosedural atau imperatif, bukan karakteristik kode berorientasi objek "baik". Ini bukan untuk mengatakan paradigma prosedural itu buruk, tetapi saya mendapat kesan atasan Anda mengharapkan Anda untuk menulis "kode berorientasi objek yang baik" dan Anda benar-benar ingin menulis "

Ada banyak gotcha di Jawa ketika Anda mulai menggunakan statika yang tidak selalu langsung terlihat jelas. Misalnya, jika Anda memiliki dua salinan dari program Anda yang berjalan di VM yang sama, apakah mereka akan mengubah nilai variabel statis dan mengacaukan keadaan satu sama lain? Atau apa yang terjadi ketika Anda memperluas kelas, dapatkah Anda mengganti anggota statis? Apakah VM Anda kehabisan memori karena Anda memiliki jumlah statika yang gila dan bahwa memori tidak dapat direklamasi untuk objek instance lain yang diperlukan?

Obyek Seumur Hidup: Selain itu, statika memiliki masa hidup yang cocok dengan seluruh runtime program. Ini berarti, bahkan setelah Anda selesai menggunakan kelas Anda, memori dari semua variabel statis tidak dapat dikumpulkan sampah. Jika, misalnya, sebagai gantinya, Anda membuat variabel Anda non-statis, dan pada fungsi utama Anda (), Anda membuat instance tunggal dari kelas Anda, dan kemudian meminta kelas Anda untuk menjalankan fungsi tertentu 10.000 kali, setelah 10.000 panggilan dilakukan , dan Anda menghapus referensi Anda ke satu contoh, semua variabel statis Anda bisa menjadi sampah yang dikumpulkan dan digunakan kembali.

Mencegah penggunaan ulang tertentu: Selain itu, metode statis tidak dapat digunakan untuk mengimplementasikan antarmuka, sehingga metode statis dapat mencegah fitur berorientasi objek tertentu agar tidak dapat digunakan.

Pilihan lain: Jika efisiensi adalah perhatian utama Anda, mungkin ada cara lain yang lebih baik untuk memecahkan masalah kecepatan daripada hanya mempertimbangkan keuntungan doa biasanya lebih cepat daripada penciptaan. Pertimbangkan apakah pengubah transien atau volatil diperlukan di mana saja. Untuk mempertahankan kemampuan yang akan diuraikan, suatu metode dapat ditandai sebagai final alih-alih statis. Parameter metode dan variabel lainnya dapat ditandai sebagai final untuk mengizinkan optimiaisasi kompiler tertentu berdasarkan pada asumsi tentang apa yang dapat mengubah variabel-variabel tersebut. Objek instance dapat digunakan kembali beberapa kali daripada membuat instance baru setiap kali. Mungkin ada saklar optimisasi kompiler yang harus dihidupkan untuk aplikasi secara umum. Mungkin, desain harus diatur sehingga 10.000 berjalan dapat multi-threaded dan memanfaatkan core multi-prosesor. Jika portablity tidak

Jika karena alasan tertentu Anda tidak ingin banyak salinan dari suatu objek, pola desain tunggal, memiliki kelebihan dibandingkan objek statis, seperti keamanan ulir (menganggap singleton Anda dikodekan dengan baik), memungkinkan inisialisasi malas, menjamin objek telah diinisialisasi dengan benar ketika digunakan, sub-klasifikasi, keuntungan dalam pengujian dan refactoring kode Anda, belum lagi, jika pada titik tertentu Anda berubah pikiran tentang hanya menginginkan satu instance objek, JAUH lebih mudah untuk menghapus kode untuk mencegah duplikat instance daripada untuk refactor semua kode variabel statis Anda untuk menggunakan variabel instance. Saya harus melakukan itu sebelumnya, itu tidak menyenangkan, dan Anda akhirnya harus mengedit lebih banyak kelas, yang meningkatkan risiko memperkenalkan bug baru ... jauh lebih baik untuk mengatur hal-hal "benar" pertama kali, bahkan jika itu sepertinya memiliki kelemahan. Untuk saya, pengerjaan ulang yang diperlukan jika Anda memutuskan jalan yang Anda butuhkan beberapa salinan sesuatu mungkin merupakan salah satu alasan yang paling menarik untuk menggunakan statika sesering mungkin. Dan dengan demikian saya juga tidak setuju dengan pernyataan Anda bahwa statika mengurangi inter-dependensi, saya pikir Anda akan berakhir dengan kode yang lebih digabungkan jika Anda memiliki banyak statika yang dapat langsung diakses, daripada objek yang "tahu bagaimana melakukan sesuatu "pada dirinya sendiri.

Jessica Brown
sumber
11
Saya suka jawaban Anda, saya pikir ini berfokus pada tradeoffs yang tepat untuk dipertimbangkan di sekitar statika daripada beberapa ikan haring merah seperti konkurensi dan ruang lingkup. Dan +1 untuk lajang, pertanyaan yang lebih baik mungkin saat menggunakan variabel statis / metode vs lajang ...
studgeek
2
Meskipun singleton itu sendiri mungkin thread-safe (misalnya dengan menggunakan synchronizedmetode), itu tidak berarti kode panggilan bebas dari kondisi ras sehubungan dengan negara singleton.
André Caron
8
Juga, statika tidak bertentangan dengan paradigma OOP. Banyak fanatik OOP akan memberi tahu Anda bahwa kelas adalah objek, dan metode statis adalah metode objek kelas, daripada instance itu. Fenomena ini kurang hadir di Jawa. Bahasa lain, seperti Python memungkinkan Anda untuk menggunakan kelas sebagai variabel dan Anda dapat mengakses metode statis sebagai metode objek itu.
André Caron
4
Baris terakhir dari paragraf ketiga harus dibaca, semua variabel non-statis Anda , jika saya tidak salah.
Steve
1
Object Lifetime, adalah satu hal yang sangat penting yang @jessica sebutkan.
Abhidemon
93

Kejahatan adalah istilah subyektif.

Anda tidak mengendalikan statika dalam hal penciptaan dan penghancuran. Mereka hidup atas perintah program bongkar muat.

Karena statika hidup dalam satu ruang, semua utas yang ingin menggunakannya harus melalui kontrol akses yang harus Anda kelola. Ini berarti bahwa program lebih digabungkan dan perubahan ini lebih sulit untuk dibayangkan dan dikelola (seperti kata J Skeet). Ini mengarah pada masalah mengisolasi dampak perubahan dan dengan demikian mempengaruhi bagaimana pengujian dikelola.

Ini adalah dua masalah utama yang saya miliki dengan mereka.

Praha Sangha
sumber
59

Tidak. Negara-negara global tidak jahat pada dasarnya. Tetapi kami harus melihat kode Anda untuk melihat apakah Anda menggunakannya dengan benar. Sangat mungkin bahwa seorang pemula melecehkan negara-negara global; sama seperti dia akan menyalahgunakan setiap fitur bahasa.

Negara-negara global adalah kebutuhan mutlak. Kita tidak bisa menghindari negara global. Kita tidak dapat menghindari alasan tentang negara global. - Jika kita ingin memahami semantik aplikasi kita.

Orang-orang yang berusaha untuk menyingkirkan negara-negara global demi hal itu, pasti berakhir dengan sistem yang jauh lebih kompleks - dan negara-negara global masih ada di sana, secara cerdik / bodoh menyamar di bawah banyak lapisan tipuan; dan kita masih harus bernalar tentang negara-negara global, setelah membuka semua tipuan.

Seperti orang-orang Spring yang dengan boros menyatakan negara global dalam xml dan berpikir entah bagaimana itu lebih unggul.

@ Jon Skeet if I create a new instance of an objectsekarang Anda memiliki dua hal yang perlu dipikirkan - keadaan dalam objek, dan keadaan lingkungan yang menampung objek.

tak dapat disangkal
sumber
10
"Aku punya dua hal untuk dipikirkan". Tidak jika saya membuat tes saya hanya bergantung pada status objek. Yang lebih mudah, semakin sedikit keadaan global yang saya miliki.
DJClayworth
2
Injeksi ketergantungan tidak ada hubungannya dengan keadaan global atau visibilitas global - bahkan wadah itu sendiri bukan global. Dibandingkan dengan kode "normal", satu-satunya hal tambahan yang dapat dilihat oleh objek yang dikelola wadah adalah kontainer itu sendiri. Faktanya, DI sangat umum digunakan untuk menghindari Pola Singleton.
Floegipoky
31

Ada 2 masalah utama dengan variabel statis:

  • Thread Safety - sumber daya statis secara definisi tidak aman untuk thread
  • Implisitas Kode - Anda tidak tahu kapan variabel statis di-instantiated dan apakah itu akan di-instantiate sebelum variabel statis lain
sternr
sumber
Saya pikir Jon Skeet merujuk komentar yang sama yang Anda posting.
RG-3
13
Saya tidak mendapatkan poin Keamanan Utas, saya pikir tidak ada yang aman kecuali Anda membuatnya begitu. Ini sepertinya tidak berhubungan dengan hal-hal statis sama sekali, mohon koreksi saya jika saya kehilangan sesuatu.
Zmaster
1
@ Zmaster - Meskipun benar bahwa keselamatan-thread bukan masalah eksklusif untuk variabel statis, karena menurut definisi mereka dipanggil dari dan oleh konteks yang berbeda, mereka lebih memangkasnya
sternr
2
@sternr Saya mengerti apa yang Anda maksud, acara jika "konteks yang berbeda" tidak harus sama dengan "utas berbeda". Tetapi memang benar bahwa keselamatan ulir perlu sering diperhitungkan dengan sumber daya statis. Anda harus mempertimbangkan untuk memperjelas kalimatnya.
Zmaster
Ada penggunaan aman sumber daya statis yang valid, misalnya. private Logger final static LOG = Logger.getLogger (Foo.class); final AtomicInteger statis x = AtomicInteger baru (0); Seperti yang saya pahami, penetapan sumber daya statis seperti ini dijamin aman oleh loader kelas. Instance Logger adalah aman-aman atau tidak terlepas dari tempat Anda menetapkan pointer ke sana. Mempertahankan status dalam statika mungkin bukan ide yang baik, tetapi tidak ada alasan untuk tidak menggunakan thread-safe.
teknopaul
29

Jika Anda menggunakan kata kunci 'statis' tanpa kata kunci 'final', ini harus menjadi sinyal untuk mempertimbangkan dengan cermat desain Anda. Bahkan kehadiran 'final' bukanlah jalan bebas, karena objek final statis yang dapat berubah bisa sama berbahayanya.

Saya akan memperkirakan sekitar 85% dari waktu saya melihat 'statis' tanpa 'final', itu SALAH. Seringkali, saya akan menemukan solusi aneh untuk menutupi atau menyembunyikan masalah ini.

Tolong jangan membuat mutables statis. Terutama Koleksi. Secara umum, Koleksi harus diinisialisasi ketika objek yang berisi diinisialisasi dan harus dirancang sehingga mereka diatur ulang atau dilupakan ketika objek yang mengandung mereka dilupakan.

Menggunakan statika dapat membuat bug yang sangat halus yang akan menyebabkan hari-hari kesakitan para insinyur. Saya tahu, karena saya telah membuat dan memburu bug ini.

Jika Anda ingin lebih detail, baca terus ...

Kenapa Tidak Menggunakan Statika?

Ada banyak masalah dengan statika, termasuk penulisan dan pelaksanaan tes, serta bug halus yang tidak segera terlihat.

Kode yang bergantung pada objek statis tidak dapat dengan mudah diuji unit, dan statika tidak dapat dengan mudah diejek (biasanya).

Jika Anda menggunakan statika, tidak mungkin untuk menukar implementasi kelas keluar untuk menguji komponen tingkat yang lebih tinggi. Misalnya, bayangkan CustomerDAO statis yang mengembalikan objek Pelanggan yang dimuatnya dari database. Sekarang saya memiliki CustomerFilter kelas, yang perlu mengakses beberapa objek Pelanggan. Jika CustomerDAO statis, saya tidak bisa menulis tes untuk CustomerFilter tanpa terlebih dahulu menginisialisasi database saya dan mengisi informasi yang berguna.

Dan populasi basis data dan inisialisasi membutuhkan waktu lama. Dan dalam pengalaman saya, kerangka inisialisasi DB Anda akan berubah seiring waktu, yang berarti data akan berubah, dan tes mungkin rusak. IE, bayangkan Pelanggan 1 dulu VIP, tetapi kerangka inisialisasi DB berubah, dan sekarang Pelanggan 1 tidak lagi VIP, tetapi tes Anda sulit untuk memuat Pelanggan 1 ...

Pendekatan yang lebih baik adalah dengan instantiate CustomerDAO, dan meneruskannya ke CustomerFilter ketika dibangun. (Pendekatan yang lebih baik lagi adalah dengan menggunakan Spring atau kerangka kerja Inversion of Control lainnya.

Setelah Anda melakukan ini, Anda dapat dengan cepat mengejek atau mematikan DAO alternatif di CustomerFilterTest Anda, yang memungkinkan Anda untuk memiliki kontrol lebih besar atas tes,

Tanpa DAO statis, pengujian akan lebih cepat (tanpa inisialisasi db) dan lebih dapat diandalkan (karena tidak akan gagal ketika kode inisialisasi db berubah). Misalnya, dalam hal ini memastikan Pelanggan 1 adalah dan akan selalu menjadi VIP, sejauh menyangkut pengujian.

Melaksanakan Tes

Statika menyebabkan masalah nyata ketika menjalankan suite unit test bersama (misalnya, dengan server Integrasi Berkelanjutan Anda). Bayangkan peta statis objek Socket jaringan yang tetap terbuka dari satu pengujian ke pengujian lainnya. Tes pertama mungkin membuka Socket pada port 8080, tetapi Anda lupa untuk menghapus Peta saat tes dihancurkan. Sekarang ketika tes kedua diluncurkan, kemungkinan akan macet ketika mencoba membuat Socket baru untuk port 8080, karena port tersebut masih ditempati. Bayangkan juga bahwa referensi Socket di Koleksi statis Anda tidak dihapus, dan (dengan pengecualian WeakHashMap) tidak pernah memenuhi syarat untuk menjadi sampah yang dikumpulkan, menyebabkan kebocoran memori.

Ini adalah contoh yang terlalu umum, tetapi dalam sistem besar, masalah ini terjadi SELAMA WAKTU. Orang-orang tidak memikirkan pengujian unit yang memulai dan menghentikan perangkat lunak mereka berulang kali dalam JVM yang sama, tetapi ini adalah tes yang bagus untuk desain perangkat lunak Anda, dan jika Anda memiliki aspirasi terhadap ketersediaan tinggi, itu adalah sesuatu yang perlu Anda waspadai.

Masalah-masalah ini sering muncul dengan objek kerangka kerja, misalnya, akses DB Anda, caching, pesan, dan lapisan logging. Jika Anda menggunakan Java EE atau beberapa kerangka kerja terbaik, mereka mungkin mengelola banyak hal ini untuk Anda, tetapi jika seperti saya Anda berurusan dengan sistem warisan, Anda mungkin memiliki banyak kerangka kerja khusus untuk mengakses lapisan ini.

Jika konfigurasi sistem yang berlaku untuk komponen kerangka ini berubah di antara pengujian unit, dan kerangka kerja pengujian unit tidak meruntuhkan dan membangun kembali komponen, perubahan ini tidak dapat berlaku, dan ketika tes bergantung pada perubahan itu, mereka akan gagal .

Bahkan komponen non-kerangka kerja tunduk pada masalah ini. Bayangkan sebuah peta statis yang disebut OpenOrders. Anda menulis satu tes yang menciptakan beberapa pesanan terbuka, dan memeriksa untuk memastikan semuanya dalam kondisi yang benar, kemudian tes berakhir. Pengembang lain menulis tes kedua yang menempatkan pesanan yang dibutuhkan ke dalam peta OpenOrders, lalu menegaskan jumlah pesanan yang akurat. Jalankan satu per satu, kedua tes ini akan lulus, tetapi ketika dijalankan bersama dalam sebuah suite, keduanya akan gagal.

Lebih buruk lagi, kegagalan mungkin didasarkan pada urutan di mana tes dijalankan.

Dalam hal ini, dengan menghindari statika, Anda menghindari risiko data yang bertahan di seluruh contoh uji, memastikan keandalan tes yang lebih baik.

Bug Halus

Jika Anda bekerja di lingkungan dengan ketersediaan tinggi, atau di mana pun thread dapat dimulai dan dihentikan, masalah yang sama yang disebutkan di atas dengan unit test suites dapat berlaku ketika kode Anda juga berjalan pada produksi.

Saat berurusan dengan utas, daripada menggunakan objek statis untuk menyimpan data, lebih baik menggunakan objek yang diinisialisasi selama fase startup utas. Dengan cara ini, setiap kali utas dimulai, instance objek baru (dengan konfigurasi yang berpotensi baru) dibuat, dan Anda menghindari data dari satu instance thread yang berdarah hingga instance berikutnya.

Ketika sebuah utas mati, objek statis tidak dapat direset atau sampah dikumpulkan. Bayangkan Anda memiliki utas yang disebut "EmailCustomers", dan ketika mulai itu mengisi kumpulan String statis dengan daftar alamat email, kemudian mulai mengirim email masing-masing alamat. Katakanlah utasnya terputus atau dibatalkan, jadi kerangka kerja ketersediaan tinggi Anda memulai ulang utas. Kemudian ketika utas dimulai, ia memuat kembali daftar pelanggan. Tetapi karena koleksinya statis, ia mungkin mempertahankan daftar alamat email dari koleksi sebelumnya. Sekarang beberapa pelanggan mungkin mendapatkan email rangkap.

An Aside: Final Statis

Penggunaan "final statis" secara efektif setara dengan Java dari definisi C #, meskipun ada perbedaan implementasi teknis. AC / C ++ #define diganti dari kode oleh pra-prosesor, sebelum dikompilasi. Java "static final" akan berakhir dengan memori yang tersimpan di stack. Dengan cara itu, ini lebih mirip dengan variabel "static const" di C ++ daripada ke #define.

Ringkasan

Saya harap ini membantu menjelaskan beberapa alasan dasar mengapa statika bermasalah. Jika Anda menggunakan kerangka kerja Java modern seperti Java EE atau Spring, dll, Anda mungkin tidak menemukan banyak dari situasi ini, tetapi jika Anda bekerja dengan tubuh besar kode warisan, mereka bisa menjadi jauh lebih sering.

JBCP
sumber
15

Karena tidak ada * yang menyebutkannya: concurrency. Variabel statis dapat mengejutkan Anda jika Anda memiliki beberapa utas membaca dan menulis ke variabel statis. Ini biasa terjadi pada aplikasi web (mis., ASP.NET) dan dapat menyebabkan beberapa bug yang agak menjengkelkan. Misalnya, jika Anda memiliki variabel statis yang diperbarui oleh halaman, dan halaman tersebut diminta oleh dua orang pada "waktu yang hampir bersamaan", satu pengguna mungkin mendapatkan hasil yang diharapkan oleh pengguna lain, atau lebih buruk.

statika mengurangi saling ketergantungan pada bagian lain dari kode. Mereka dapat bertindak sebagai pemegang negara yang sempurna

Saya harap Anda siap menggunakan kunci dan berurusan dengan pertengkaran.

* Sebenarnya, Preha Sangha menyebutkannya.

Justin M. Keyes
sumber
5
Variabel Instance tidak memiliki keunggulan thread-safety dibandingkan statika, mereka semua adalah variabel yang tidak dilindungi. Sebaliknya, itu semua bermuara pada bagaimana Anda melindungi kode yang mengakses variabel-variabel itu.
studgeek
2
Saya tidak cukup membuat klaim itu, tetapi demi diskusi: pemisahan adalah bentuk perlindungan. Status utas dipisahkan; negara global tidak . Variabel instan tidak perlu perlindungan kecuali itu dibagi secara eksplisit di antara utas; variabel statis selalu dibagikan oleh semua utas dalam proses.
Justin M. Keyes
Saya berharap variabel thread-statis lebih merupakan konsep kelas satu, karena mereka dapat sangat berguna untuk membuat informasi tersedia dengan aman untuk panggilan subrutin yang dibungkus tanpa harus meneruskan informasi itu melalui setiap lapisan pembungkus. Sebagai contoh, jika suatu objek memiliki metode untuk merendernya ke konteks grafik thread saat ini, dan ada metode untuk menyimpan / mengembalikan konteks grafik saat ini, menggunakan yang sering bisa lebih bersih daripada harus melewati konteks grafik melalui setiap pemanggilan metode.
supercat
15

Meringkas beberapa Keuntungan dasar & Kerugian menggunakan metode statis di Jawa:

Keuntungan:

  1. Dapat diakses secara global yaitu tidak terikat dengan instance objek tertentu.
  2. Satu contoh per JVM.
  3. Dapat diakses dengan menggunakan nama kelas (Tidak perlu objek).
  4. Berisi nilai tunggal yang berlaku untuk semua instance.
  5. Memuat pada startup JVM dan mati ketika JVM dimatikan.
  6. Mereka tidak mengubah status Object.

Kekurangan:

  1. Anggota statis selalu menjadi bagian dari memori apakah mereka sedang digunakan atau tidak.
  2. Anda tidak dapat mengontrol pembuatan dan penghancuran variabel statis. Berguna mereka telah dibuat pada pemuatan program dan dihancurkan ketika program diturunkan (atau ketika JVM dimatikan).
  3. Anda dapat membuat thread statika aman menggunakan sinkronisasi tetapi Anda perlu upaya ekstra.
  4. Jika satu utas mengubah nilai variabel statis yang mungkin dapat merusak fungsionalitas utas lainnya.
  5. Anda harus tahu "statis" sebelum menggunakannya.
  6. Anda tidak dapat mengganti metode statis.
  7. Serialisasi tidak bekerja dengan baik dengan mereka.
  8. Mereka tidak berpartisipasi dalam polimorfisme runtime.
  9. Ada masalah memori (sampai batas tertentu tetapi tidak banyak yang saya kira) jika sejumlah besar variabel / metode statis digunakan. Karena mereka tidak akan Terkumpul Sampah sampai program berakhir.
  10. Metode statis juga sulit untuk diuji.
Affy
sumber
Kerugian 6, 7, 8 dan 10 adalah kerugian dari bahasa / kerangka kerja yang digunakan, dan bukan kerugian dari variabel statis secara umum. Kerugian 1, 4 dan 5 ada juga untuk solusi lain, seperti beberapa pola tunggal yang disediakan oleh beberapa kerangka kerja. (Saya tidak memilih jawaban, karena saya setuju sisanya dan itu adalah koleksi yang bagus.)
peterh - Reinstate Monica
13

jika saya harus membuat 10.000 panggilan ke fungsi dalam suatu kelas, saya akan senang untuk membuat metode statis dan menggunakan class.methodCall langsung () di atasnya bukannya mengacaukan memori dengan 10.000 contoh kelas, kan?

Anda harus menyeimbangkan kebutuhan untuk merangkum data menjadi objek dengan keadaan, dibandingkan kebutuhan hanya menghitung hasil fungsi pada beberapa data.

Selain itu statika mengurangi saling ketergantungan pada bagian lain dari kode.

Begitu juga enkapsulasi. Dalam aplikasi besar, statika cenderung menghasilkan kode spageti dan tidak mudah memungkinkan refactoring atau pengujian.

Jawaban lain juga memberikan alasan yang bagus untuk tidak menggunakan statika secara berlebihan.

Jérôme Verstrynge
sumber
13

Variabel statis umumnya dianggap buruk karena mereka mewakili negara global dan karenanya jauh lebih sulit untuk dipikirkan. Secara khusus, mereka mematahkan asumsi pemrograman berorientasi objek. Dalam pemrograman berorientasi objek, setiap objek memiliki statusnya sendiri, diwakili oleh variabel instance (non-statis). Variabel statis mewakili keadaan lintas instance yang jauh lebih sulit untuk diuji unit. Ini terutama karena lebih sulit untuk mengisolasi perubahan pada variabel statis ke tes tunggal.

Yang sedang berkata, penting untuk membuat perbedaan antara variabel statis reguler (umumnya dianggap buruk), dan variabel statis akhir (konstanta AKA; tidak begitu buruk).

Jack Edmonds
sumber
4
"Variabel statis mewakili negara di seluruh kelas" "Saya pikir maksud Anda" variabel statis mewakili negara di seluruh instance "? +1 untuk "konstanta AKA statis akhir, tidak terlalu buruk". Karena nilainya tidak dapat berubah, apa pun yang bergantung padanya pada satu titik waktu tidak dapat secara implisit mengubah perilakunya di lain waktu - nilainya sama.
Jared Updike
"Variabel statis mewakili keadaan di seluruh instance" adalah cara yang lebih baik untuk menyatakannya. Saya sudah mengedit jawaban saya.
Jack Edmonds
9

Menurut saya ini hampir tidak pernah tentang kinerja, ini tentang desain. Saya tidak menganggap penggunaan metode statis yang salah sebagai apposed penggunaan variabel statis (tapi saya kira Anda benar-benar berbicara tentang panggilan metode).

Ini hanya tentang bagaimana mengisolasi logika dan memberinya tempat yang baik. Terkadang itu dibenarkan menggunakan metode statis yang java.lang.Mathmerupakan contoh yang baik. Saya pikir ketika Anda menyebutkan sebagian besar kelas Anda XxxUtilatau XxxhelperAnda sebaiknya mempertimbangkan kembali desain Anda.

M Platvoet
sumber
3
Metode statis bebas efek samping murni adalah IMO yang sangat baik. Tetapi negara yang bisa berubah global jarang dan saya menafsirkan OP sebagai berbicara tentang negara global.
CodesInChaos
1
@CodeInChaos sepenuhnya setuju. Saya menemukan OP tidak sepenuhnya jelas tentang perbedaan antara metode statis dan vars.
M Platvoet
8

Saya baru saja merangkum beberapa poin yang dibuat dalam jawaban. Jika Anda menemukan sesuatu yang salah, silakan memperbaikinya.

Penskalaan: Kami memiliki tepat satu contoh variabel statis per JVM. Misalkan kita sedang mengembangkan sistem manajemen perpustakaan dan kami memutuskan untuk menempatkan nama buku variabel statis karena hanya ada satu per buku. Tetapi jika sistem tumbuh dan kami menggunakan beberapa JVM maka kami tidak punya cara untuk mencari tahu buku mana yang sedang kami tangani?

Thread-Safety: Baik variabel instan dan variabel statis perlu dikendalikan ketika digunakan di lingkungan multi-ulir. Tetapi dalam kasus variabel instan tidak perlu perlindungan kecuali itu dibagi secara eksplisit antara thread tetapi dalam kasus variabel statis selalu dibagi oleh semua thread dalam proses.

Pengujian: Meskipun desain yang dapat diuji tidak sama dengan desain yang baik tetapi kami jarang akan mengamati desain yang baik yang tidak dapat diuji. Karena variabel statis mewakili keadaan global dan akan sangat sulit untuk mengujinya.

Penalaran tentang keadaan: Jika saya membuat instance baru dari sebuah kelas maka kita dapat alasan tentang keadaan instance ini tetapi jika ia memiliki variabel statis maka bisa dalam keadaan apa pun. Mengapa? Karena ada kemungkinan variabel statis telah dimodifikasi oleh beberapa instance yang berbeda karena variabel statis dibagikan di seluruh instance.

Serialisasi: Serialisasi juga tidak berfungsi dengan baik.

Penciptaan dan penghancuran: Penciptaan dan penghancuran variabel statis tidak dapat dikontrol. Biasanya mereka dibuat dan dihancurkan pada waktu pemuatan dan pembongkaran program. Ini berarti mereka buruk untuk manajemen memori dan juga menambah waktu inisialisasi saat start up.

Tetapi bagaimana jika kita benar-benar membutuhkannya?

Tetapi kadang-kadang kita mungkin benar-benar membutuhkannya. Jika kita benar-benar merasakan perlunya banyak variabel statis yang dibagikan di seluruh aplikasi maka salah satu opsi adalah menggunakan pola Desain Singleton yang akan memiliki semua variabel ini. Atau kita dapat membuat beberapa objek yang akan memiliki variabel statis ini dan dapat diedarkan.

Juga jika variabel statis ditandai final, itu menjadi konstanta dan nilai yang diberikan setelah itu tidak dapat diubah. Itu berarti akan menyelamatkan kita dari semua masalah yang kita hadapi karena sifatnya yang berubah-ubah.

akhil_mittal
sumber
7

Menurut saya Anda bertanya tentang variabel statis tetapi Anda juga menunjukkan metode statis dalam contoh Anda.

Variabel statis tidak jahat - mereka memiliki adopsi sebagai variabel global seperti konstanta dalam banyak kasus dikombinasikan dengan pengubah akhir, tetapi seperti dikatakan tidak terlalu sering menggunakannya.

Metode statis alias metode utilitas. Biasanya bukan praktik buruk untuk menggunakannya, tetapi kekhawatiran utama adalah bahwa mereka dapat menghalangi pengujian.

Sebagai contoh proyek java yang hebat yang menggunakan banyak statika dan melakukannya dengan cara yang benar, silakan lihat Play! framework . Ada juga diskusi tentang hal itu di SO.

Variabel / metode statis dikombinasikan dengan impor statis juga banyak digunakan di perpustakaan yang memfasilitasi pemrograman deklaratif di java seperti: membuatnya mudah atau Hamcrest . Itu tidak akan mungkin terjadi tanpa banyak variabel dan metode statis.

Jadi variabel statis (dan metode) bagus tetapi gunakan dengan bijak!

cetnar
sumber
6

Variabel statis yang paling penting menciptakan masalah dengan keamanan data (setiap kali diubah, siapa pun dapat berubah, akses langsung tanpa objek, dll.)

Untuk info lebih lanjut baca ini Terima kasih.

Anuj Patel
sumber
6

Mungkin disarankan bahwa dalam kebanyakan kasus di mana Anda menggunakan variabel statis, Anda benar-benar ingin menggunakan pola tunggal .

Masalah dengan negara-negara global adalah bahwa kadang-kadang apa yang masuk akal sebagai global dalam konteks yang lebih sederhana, perlu sedikit lebih fleksibel dalam konteks praktis, dan di sinilah pola tunggal menjadi berguna.

Charles Goodwin
sumber
5

Namun alasan lain: kerapuhan.

Jika Anda memiliki kelas, kebanyakan orang berharap dapat membuatnya dan menggunakannya sesuka hati.

Anda dapat mendokumentasikannya bukan kasusnya, atau melindunginya (pola tunggal / pabrik) - tapi itu pekerjaan tambahan, dan karenanya merupakan biaya tambahan. Bahkan kemudian, di sebuah perusahaan besar, kemungkinan seseorang akan mencoba di beberapa titik untuk menggunakan kelas Anda tanpa sepenuhnya memperhatikan semua komentar atau pabrik yang bagus.

Jika Anda banyak menggunakan variabel statis, itu akan rusak. Bug itu mahal.

Antara peningkatan kinerja .0001% dan ketahanan untuk berubah oleh pengembang yang berpotensi tidak mengerti, dalam banyak kasus ketahanan adalah pilihan yang baik.

ptyx
sumber
4

Saya menemukan variabel statis lebih nyaman digunakan. Dan saya menganggap bahwa mereka juga efisien (Harap perbaiki saya jika saya salah) karena jika saya harus membuat 10.000 panggilan ke suatu fungsi dalam suatu kelas, saya akan senang untuk membuat metode ini statis dan menggunakan class.methodCall () yang mudah di atasnya bukannya mengacaukan memori dengan 10.000 contoh kelas, Benar?

Saya mengerti apa yang Anda pikirkan, tetapi pola Singleton sederhana akan melakukan hal yang sama tanpa harus membuat instance 10.000 objek.

metode statis dapat digunakan, tetapi hanya untuk fungsi yang berhubungan dengan domain objek dan tidak perlu atau menggunakan properti internal objek.

ex:

public class WaterContainer {
    private int size;
    private int brand;
    ...etc

    public static int convertToGallon(int liters)...

    public static int convertToLiters(int gallon)...

}
Cygnusx1
sumber
Singleton klasik (yaitu yang diakses oleh Class.Instance) hampir tidak lebih baik daripada variabel statis. Ini sedikit lebih dapat diuji, tetapi masih jauh lebih buruk daripada desain di mana Anda kebetulan membuat satu contoh bukannya membangun kode Anda dengan asumsi hanya ada satu.
CodesInChaos
Tidak yakin saya mengerti komentar Anda! Saya menanggapi OP tentang apa yang ia nyatakan dalam huruf miring tentang pemasangan 10.000 objek. Saya tidak mengerti mengapa Anda membandingkan variabel tunggal dan variabel statis? Apa yang saya mengerti dari apa yang Anda tulis adalah bahwa Singleton adalah desain yang buruk ...! Saya kira saya salah paham, karena Spring Framework secara default membuat semua kacang Singleton ;-)
Cygnusx1
Singleton klasik (yang memiliki Class.Instance) yang membawa keadaan bisa berubah adalah IMO desain yang buruk. Dalam hal ini saya sangat suka desain di mana saya mendapatkan lajang saya perlu menggunakan diteruskan sebagai parameter ke dalam kelas yang menggunakannya (biasanya dengan bantuan DI). Lajang klasik yang tidak dapat diubah secara logis adalah IMO yang baik.
CodesInChaos
@ Cygnusx1 Seandainya tidak jelas mengapa Class singleton (singleton di mana kelas memastikan satu salinan) tidak mudah diuji, itu secara ketat memasangkan keberadaan kelas ke siklus hidup program. Untuk mengujinya, Anda harus mematuhi peluncuran dan penghentian program, yang sering memiliki efek samping yang tidak penting untuk menguji kelas. Jika itu secara efektif sebagai singleton (satu salinan dalam program, tetapi bukan penegakan lain), Anda dapat membuat banyak salinan pada waktu ujian tanpa program, memverifikasi bahwa perilaku di seluruh kelas adalah sebagaimana mestinya untuk setiap skenario pengujian.
Edwin Buck
4

Masalah 'Statika menjadi jahat' lebih merupakan masalah tentang negara global. Waktu yang tepat untuk variabel menjadi statis, adalah jika tidak pernah memiliki lebih dari satu negara; Alat IE yang harus dapat diakses oleh seluruh kerangka kerja dan selalu mengembalikan hasil yang sama untuk panggilan metode yang sama tidak pernah 'jahat' seperti statika. Seperti untuk komentar Anda:

Saya menemukan variabel statis lebih nyaman digunakan. Dan saya kira mereka juga efisien

Statika adalah pilihan ideal dan efisien untuk variabel / kelas yang tidak pernah berubah .

Masalah dengan negara global adalah ketidakkonsistenan inheren yang dapat diciptakannya. Dokumentasi tentang pengujian unit sering mengatasi masalah ini, karena setiap saat ada keadaan global yang dapat diakses oleh lebih dari beberapa objek yang tidak terkait, pengujian unit Anda akan tidak lengkap, dan tidak berbutir 'unit'. Seperti yang disebutkan dalam artikel ini tentang negara global dan lajang , jika objek A dan B tidak terkait (karena dalam satu tidak secara tegas diberikan referensi ke yang lain), maka A seharusnya tidak dapat mempengaruhi keadaan B.

Ada beberapa pengecualian untuk larangan negara global dalam kode yang baik, seperti jam. Waktu bersifat global, dan - dalam arti tertentu - waktu mengubah keadaan objek tanpa memiliki hubungan kode.

Bryan Agee
sumber
"Waktu adalah global" - ada cara lain untuk memodelkan waktu dalam sistem komputasi selain menjadikannya suatu hal global yang tersirat yang berubah dengan sendirinya. lih. survei ini: "Modeling Time in Computing: A Taxonomy and a Comparative Survey" @ arxiv.org/abs/0807.4132
Jared Updike
4

$ 0,02 saya adalah bahwa beberapa jawaban ini membingungkan masalah ini, daripada mengatakan "statika itu buruk" Saya pikir lebih baik untuk berbicara tentang pelingkupan dan contoh.

Apa yang akan saya katakan adalah bahwa statis adalah variabel "kelas" - itu mewakili nilai yang dibagikan di semua contoh kelas itu. Biasanya harus dicakup juga (dilindungi atau pribadi untuk kelas dan instansnya).

Jika Anda berencana untuk menempatkan perilaku tingkat kelas di sekitarnya dan memaparkannya ke kode lain, maka singleton mungkin merupakan solusi yang lebih baik untuk mendukung perubahan di masa depan (seperti yang disarankan @Jessica). Ini karena Anda dapat menggunakan antarmuka pada tingkat instance / singleton dengan cara yang tidak dapat Anda gunakan di tingkat kelas - khususnya warisan.

Beberapa pemikiran tentang mengapa saya pikir beberapa aspek dalam jawaban lain bukanlah inti dari pertanyaan ...

Statika bukan "global". Dalam Java scoping dikontrol secara terpisah dari static / instance.

Concurrency tidak kalah berbahaya untuk statika daripada metode instance. Itu masih menyatakan bahwa perlu dilindungi. Tentu Anda memiliki 1000 instance dengan masing-masing variabel instan dan hanya satu variabel statis, tetapi jika kode yang mengakses keduanya tidak ditulis dengan cara aman, Anda masih kacau - mungkin perlu sedikit waktu lebih lama bagi Anda untuk menyadarinya .

Mengelola siklus hidup adalah argumen yang menarik, tetapi saya pikir itu kurang penting. Saya tidak melihat mengapa lebih sulit untuk mengelola sepasang metode kelas seperti init () / clear () daripada penciptaan dan penghancuran instance tunggal. Bahkan, beberapa orang mungkin mengatakan singleton sedikit lebih rumit karena GC.

PS, Dalam hal Smalltalk, banyak dialeknya memang memiliki variabel kelas, tetapi dalam kelas Smalltalk sebenarnya adalah instance dari Metaclass sehingga mereka benar-benar adalah variabel pada instance Metaclass. Meski begitu, saya akan menerapkan aturan praktis yang sama. Jika mereka digunakan untuk keadaan bersama di seluruh instance maka ok. Jika mereka mendukung fungsi publik, Anda harus melihat Singleton. Sigh, aku sungguh merindukan Smalltalk ....

studgeek
sumber
4

Ada dua pertanyaan utama dalam posting Anda.

Pertama, tentang variabel statis. Variabel statis sama sekali tidak perlu dan penggunaannya dapat dihindari dengan mudah. Dalam bahasa OOP secara umum, dan di Java khususnya, parameter fungsi disusun berdasarkan referensi, ini artinya, jika Anda meneruskan objek ke funciont, Anda meneruskan pointer ke objek, jadi Anda tidak perlu mendefinisikan variabel statis karena Anda bisa meneruskan pointer ke objek ke lingkup apa pun yang membutuhkan informasi ini. Bahkan jika ini menyiratkan bahwa Anda akan mengisi memori Anda dengan pointer, ini tidak akan mewakili kinerja yang buruk karena sistem pagging memori aktual dioptimalkan untuk menangani hal ini, dan mereka akan mempertahankan dalam memori halaman yang dirujuk oleh pointer yang Anda berikan ke pointer baru. cakupan; penggunaan variabel statis dapat menyebabkan sistem memuat halaman memori di mana mereka disimpan ketika mereka perlu diakses (ini akan terjadi jika halaman tersebut belum diakses dalam waktu yang lama). Praktik yang baik adalah menyatukan semua stuf statis itu dalam beberapa "konfigurasi clases" kecil, ini akan memastikan sistem menempatkan semuanya di halaman memori yang sama.

Kedua, tentang metode statis. Metode statis tidak terlalu buruk, tetapi mereka dapat dengan cepat mengurangi kinerja. Sebagai contoh, pikirkan tentang metode yang membandingkan dua objek kelas dan mengembalikan nilai yang menunjukkan objek mana yang lebih besar (metode perbandingan tipikal) metode ini bisa statis atau tidak, tetapi ketika menjalankannya bentuk non statis akan lebih efisien karena harus menyelesaikan hanya dua referensi (satu untuk setiap objek) hadapi tiga referensi yang harus menyelesaikan versi statis dari metode yang sama (satu untuk kelas ditambah dua, satu untuk setiap objek). Tetapi seperti yang saya katakan, ini tidak terlalu buruk, jika kita melihat pada kelas Matematika, kita dapat menemukan banyak fungsi matematika yang didefinisikan sebagai metode statis. Ini benar-benar lebih efisien daripada menempatkan semua metode ini di kelas mendefinisikan angka,

Dalam kesimpulan: Hindari penggunaan variabel statis dan temukan keseimbangan kinerja yang benar ketika berhadapan dengan metode statis atau non-statis.

PS: Maaf untuk bahasa Inggris saya.

jrodriguez
sumber
4

Tidak ada yang salah dengan variabel statis per se. Hanya sintaksis Java yang rusak. Setiap kelas Java sebenarnya mendefinisikan dua struktur - objek tunggal yang merangkum variabel statis, dan sebuah instance. Mendefinisikan keduanya di blok sumber yang sama adalah kejahatan murni, dan menghasilkan kode yang sulit dibaca. Scala melakukan itu dengan benar.

Zdeněk Pavlas
sumber
3

a) Alasan tentang program.

Jika Anda memiliki program kecil hingga menengah, di mana variabel statis Global.foo diakses, panggilan ke sana biasanya datang entah dari mana - tidak ada jalur, dan oleh karena itu tidak ada garis waktu, bagaimana variabel datang ke tempat itu, di mana ia digunakan. Sekarang, bagaimana saya tahu siapa yang mengaturnya ke nilai sebenarnya? Bagaimana saya tahu, apa yang terjadi, jika saya memodifikasinya sekarang? Saya telah memahami seluruh sumber, untuk mengumpulkan semua akses, untuk mengetahui, apa yang sedang terjadi.

Jika Anda tahu cara menggunakannya, karena Anda baru saja menulis kode, masalahnya tidak terlihat, tetapi jika Anda mencoba memahami kode asing, Anda akan mengerti.

b) Apakah Anda benar-benar hanya membutuhkannya?

Variabel statis sering mencegah beberapa program dari jenis yang sama berjalan di JVM yang sama dengan nilai yang berbeda. Anda sering tidak melihat penggunaan, di mana lebih dari satu contoh program Anda berguna, tetapi jika itu berkembang, atau jika berguna bagi orang lain, mereka mungkin mengalami situasi, di mana mereka ingin memulai lebih dari satu contoh program Anda .

Hanya lebih atau kurang kode tidak berguna yang tidak akan digunakan oleh banyak orang dalam waktu yang lebih lama dengan cara intensif mungkin cocok dengan variabel statis.

Pengguna tidak diketahui
sumber
3

semuanya (dapat :) memiliki tujuannya, jika Anda memiliki banyak utas yang perlu berbagi / cache data dan juga semua memori yang dapat diakses (jadi Anda tidak membagi ke dalam konteks dalam satu JVM) statis adalah pilihan terbaik

-> tentu saja Anda dapat memaksa hanya satu contoh, tetapi mengapa?
saya menemukan beberapa komentar di utas ini jahat, bukan statika;)

tomasb
sumber
3

Variabel statis tidak baik atau jahat. Mereka mewakili atribut yang menggambarkan seluruh kelas dan bukan contoh tertentu. Jika Anda perlu memiliki penghitung untuk semua instance dari kelas tertentu, variabel statis akan menjadi tempat yang tepat untuk menyimpan nilai.

Masalah muncul ketika Anda mencoba menggunakan variabel statis untuk memegang nilai terkait contoh.

Andres
sumber
2

Semua jawaban di atas menunjukkan mengapa statika itu buruk. Alasan mereka jahat adalah karena memberikan kesan yang salah bahwa Anda menulis kode berorientasi objek, padahal sebenarnya Anda tidak. Itu benar-benar kejahatan.

orang dungu
sumber
1
Tetapi apakah secara kaku mempertimbangkan kode Anda untuk mengikuti beberapa paradigma standar sewenang-wenang sebenarnya membuat kode lebih baik, atau kita mengeluh untuk menghindari hanya menulis kode yang berfungsi?
Zoey
Ya itu memang membuatnya lebih baik, karena membuatnya lebih mudah dikelola di masa depan, lebih mudah dipahami, dan lebih eksplisit.
bodoh
1
Mengapa jahat jika tidak menulis kode OO? dan mengapa Bjarne Stroustrup tidak setuju dengan Anda? untuk menyebutkan hanya satu ...
Marquis of Lorne
2
Saya tidak mengatakan jahatnya untuk tidak menulis kode OO. Saya berkata jahat untuk berpikir Anda sedang menulis kode OO, ketika semua Anda menyamar global di belakang metode dan properti statis. Baca kembali apa yang saya tulis.
blockhead
2

Ada banyak jawaban bagus di sini, menambahkannya,

Memori: Variabel statis hidup selama loader kelas hidup [secara umum sampai VM mati], tetapi ini hanya dalam kasus objek massal / referensi yang disimpan sebagai statis.

Modularisasi: pertimbangkan konsep-konsep seperti IOC, dependencyInjection, proxy, dll. Semua sepenuhnya bertentangan dengan implementasi kopling / statis.

Lainnya Con: Keselamatan Thread, Testability

Sankarganesh Eswaran
sumber
0

Pikirkan bahwa jika Anda memiliki aplikasi dengan banyak pengguna dan Anda telah menentukan bentuk statis, maka setiap pengguna juga akan memodifikasi semua bentuk lain dari pengguna lain.

seinta
sumber
0

Saya pikir penggunaan variabel global yang berlebihan dengan kata kunci statis juga akan menyebabkan kebocoran memori pada beberapa titik misalnya di aplikasi

Rahul Anand
sumber
0

Dari sudut pandang saya, staticseharusnya hanya variabel yang hanya dibaca data atau variabel yang dibuat oleh konvensi .

Sebagai contoh, kami memiliki beberapa proyek, dan kami memiliki daftar negara, bahasa, peran pengguna, dll. Dan kami memiliki kelas untuk mengatur data ini. kami benar-benar yakin bahwa aplikasi tidak akan berfungsi tanpa daftar ini. jadi yang pertama yang kita lakukan pada aplikasi init adalah memeriksa daftar ini untuk pembaruan dan mendapatkan daftar ini dari api (jika perlu). Jadi kami setuju bahwa data ini "selalu" ada di aplikasi. Secara praktis hanya membaca data sehingga kita tidak perlu mengurus keadaannya - memikirkan kasus ini kita benar-benar tidak ingin memiliki banyak contoh data tersebut - kasus ini terlihat sebagai kandidat yang sempurna untuk menjadi statis .

qiAlex
sumber
0

Saya sering bermain dengan statika dan mungkin saya memberi Anda jawaban yang sedikit berbeda - atau mungkin cara yang sedikit berbeda untuk melihatnya?

Ketika saya menggunakan statika dalam suatu kelas (Anggota dan metode keduanya), saya akhirnya mulai memperhatikan bahwa kelas saya sebenarnya adalah dua kelas yang berbagi tanggung jawab - ada bagian "Statis" yang bertindak sangat mirip dengan seorang lajang dan ada yang tidak. -bagian statis (kelas normal). Sejauh yang saya tahu Anda selalu dapat memisahkan dua kelas sepenuhnya dengan hanya memilih semua statika untuk satu kelas dan non-statika untuk yang lain.

Ini sering terjadi ketika saya memiliki koleksi statis di dalam kelas yang menyimpan instance kelas dan beberapa metode statis untuk mengelola koleksi. Setelah Anda memikirkannya, jelas bahwa kelas Anda tidak melakukan "Hanya satu hal", itu menjadi koleksi dan melakukan sesuatu yang sama sekali berbeda.

Sekarang, mari kita sedikit memperbaiki masalahnya: Jika Anda membagi kelas Anda menjadi satu kelas di mana semuanya statis dan yang lainnya hanya merupakan "Kelas Normal" dan lupakan "Kelas Normal" maka pertanyaan Anda menjadi murni kelas statis vs Singleton yang dibahas panjang lebar di sini (dan mungkin selusin pertanyaan lain).

Bill K.
sumber