Saya cenderung mendeklarasikan sebagai statis semua metode di kelas ketika kelas itu tidak perlu melacak status internal. Misalnya, jika saya perlu mengubah A menjadi B dan tidak bergantung pada beberapa status internal C yang mungkin bervariasi, saya membuat transformasi statis. Jika ada keadaan internal C yang ingin saya sesuaikan, maka saya menambahkan konstruktor untuk menyetel C dan tidak menggunakan transformasi statis.
Saya membaca berbagai rekomendasi (termasuk di StackOverflow) TIDAK untuk terlalu sering menggunakan metode statis tetapi saya masih gagal memahami apa yang salah dengan aturan praktis di atas.
Apakah itu pendekatan yang masuk akal atau tidak?
Objek tanpa keadaan internal adalah hal yang mencurigakan.
Biasanya, objek merangkum status dan perilaku. Objek yang hanya merangkum perilaku adalah ganjil. Terkadang itu adalah contoh Lightweight atau Flyweight .
Di lain waktu, itu desain prosedural dilakukan dalam bahasa objek.
sumber
Ini benar-benar hanya tindak lanjut dari jawaban hebat John Millikin.
Meskipun aman untuk membuat metode stateless (yang memiliki banyak fungsi) statis, terkadang dapat menyebabkan kopling yang sulit untuk dimodifikasi. Anggap Anda memiliki metode statis seperti:
Yang Anda sebut sebagai:
Yang mana semuanya baik dan bagus, dan sangat nyaman, sampai Anda menemukan kasus di mana Anda harus mengubah perilaku metode statis, dan menemukan bahwa Anda terikat erat
StaticClassVersionOne
. Mungkin Anda dapat mengubah kode dan itu akan baik-baik saja, tetapi jika ada penelepon lain yang bergantung pada perilaku lama, mereka harus diperhitungkan dalam isi metode. Dalam beberapa kasus, metode tubuh bisa menjadi sangat jelek atau tidak dapat dipertahankan jika mencoba untuk menyeimbangkan semua perilaku ini. Jika Anda membagi metode, Anda mungkin harus mengubah kode di beberapa tempat untuk memperhitungkannya, atau membuat panggilan ke kelas baru.Tetapi pertimbangkan jika Anda telah membuat antarmuka untuk menyediakan metode, dan memberikannya kepada pemanggil, sekarang ketika perilakunya harus diubah, kelas baru dapat dibuat untuk mengimplementasikan antarmuka, yang lebih bersih, lebih mudah diuji, dan lebih dapat dipelihara, dan itu diberikan kepada penelepon. Dalam skenario ini, kelas pemanggil tidak perlu diubah atau bahkan dikompilasi ulang, dan perubahan tersebut dilokalkan.
Ini mungkin atau mungkin bukan situasi yang mungkin terjadi, tetapi saya pikir itu layak dipertimbangkan.
sumber
Opsi lainnya adalah menambahkannya sebagai metode non-statis pada objek asal:
yaitu, mengubah:
ke
namun dalam banyak situasi hal ini tidak mungkin (misalnya, pembuatan kode kelas reguler dari XSD / WSDL / dll), atau akan membuat kelas menjadi sangat panjang, dan metode transformasi seringkali dapat menjadi masalah yang nyata untuk objek yang kompleks dan Anda hanya menginginkannya di kelas mereka sendiri yang terpisah. Jadi ya, saya memiliki metode statis di kelas utilitas.
sumber
Kelas statis tidak masalah asalkan digunakan di tempat yang tepat.
Yaitu: Metode yang merupakan metode 'daun' (mereka tidak mengubah status, mereka hanya mengubah input). Contoh bagusnya adalah seperti Path.Combine. Hal-hal semacam ini berguna dan membuat sintaks yang lebih pendek.
The masalah yang saya miliki dengan statika banyak:
Pertama, jika Anda memiliki kelas statis, dependensi disembunyikan. Pertimbangkan hal berikut:
Melihat TextureManager, Anda tidak dapat mengetahui langkah-langkah inisialisasi apa yang harus dilakukan dengan melihat konstruktor. Anda harus mempelajari kelas untuk menemukan dependensinya dan menginisialisasi hal-hal dalam urutan yang benar. Dalam kasus ini, ResourceLoader harus diinisialisasi sebelum dijalankan. Sekarang tingkatkan mimpi buruk ketergantungan ini dan Anda mungkin bisa menebak apa yang akan terjadi. Bayangkan mencoba mempertahankan kode di mana tidak ada urutan inisialisasi yang eksplisit. Bandingkan ini dengan injeksi ketergantungan dengan instance - dalam hal ini kode bahkan tidak dapat dikompilasi jika dependensi tidak terpenuhi!
Lebih jauh lagi, jika Anda menggunakan statika yang mengubah status, ini seperti rumah kartu. Anda tidak pernah tahu siapa yang memiliki akses ke apa, dan desainnya cenderung menyerupai monster spaghetti.
Akhirnya, dan sama pentingnya, menggunakan statika mengikat program ke implementasi tertentu. Kode statis adalah antitesis dari perancangan untuk kemudahan pengujian. Menguji kode yang penuh dengan statika adalah mimpi buruk. Panggilan statis tidak pernah dapat ditukar dengan pengujian ganda (kecuali Anda menggunakan framework pengujian yang dirancang khusus untuk meniru jenis statis), sehingga sistem statis menyebabkan semua yang menggunakannya menjadi pengujian integrasi instan.
Singkatnya, statika baik-baik saja untuk beberapa hal dan untuk alat kecil atau kode sekali pakai, saya tidak akan melarang penggunaannya. Namun, di luar itu, mereka adalah mimpi buruk berdarah untuk perawatan, desain yang baik, dan kemudahan pengujian.
Berikut artikel bagus tentang masalah tersebut: http://gamearchitect.net/2008/09/13/an-anatomy-of-despair-managers-and-contexts/
sumber
Alasan Anda diperingatkan untuk menjauhi metode statis adalah karena menggunakannya akan menghilangkan salah satu keuntungan objek. Objek dimaksudkan untuk enkapsulasi data. Ini mencegah efek samping tak terduga terjadi yang menghindari bug. Metode statis tidak memiliki data yang dienkapsulasi * jadi jangan mengumpulkan manfaat ini.
Meskipun demikian, jika Anda tidak menggunakan data internal, data tersebut baik-baik saja untuk digunakan dan sedikit lebih cepat untuk dieksekusi. Pastikan Anda tidak menyentuh data global di dalamnya.
sumber
Tampaknya itu pendekatan yang masuk akal. Alasan Anda tidak ingin menggunakan terlalu banyak kelas / metode statis adalah karena Anda akhirnya beralih dari pemrograman berorientasi objek dan lebih banyak lagi ke bidang pemrograman terstruktur.
Dalam kasus Anda di mana Anda hanya mengubah A ke B, katakan semua yang kita lakukan adalah mengubah teks menjadi asal
Maka metode statis akan masuk akal.
Namun, jika Anda sering memanggil metode statis ini pada suatu objek dan cenderung unik untuk banyak panggilan (misalnya cara Anda menggunakannya bergantung pada input), atau itu adalah bagian dari perilaku inheren objek, itu akan bijaksana untuk menjadikannya bagian dari objek dan mempertahankan keadaannya. Salah satu cara untuk melakukannya adalah dengan mengimplementasikannya sebagai antarmuka.
Sunting: Salah satu contoh bagus dari penggunaan metode statis yang hebat adalah metode helper html di Asp.Net MVC atau Ruby. Mereka membuat elemen html yang tidak terikat dengan perilaku objek, dan karena itu bersifat statis.
Sunting 2: Pemrograman fungsional berubah menjadi pemrograman terstruktur (untuk beberapa alasan saya bingung), props ke Torsten untuk menunjukkannya.
sumber
Saya baru-baru ini merefaktor aplikasi untuk menghapus / memodifikasi beberapa kelas yang awalnya diimplementasikan sebagai kelas statis. Seiring waktu, kelas-kelas ini memperoleh begitu banyak dan orang-orang terus menandai fungsi baru sebagai statis, karena tidak pernah ada instance yang mengambang.
Jadi, jawaban saya adalah bahwa kelas statis tidak buruk secara inheren, tetapi mungkin lebih mudah untuk mulai membuat instance sekarang, kemudian harus melakukan refaktorisasi nanti.
sumber
Saya akan menganggapnya sebagai bau desain. Jika Anda menemukan diri Anda sebagian besar menggunakan metode statis, Anda mungkin tidak memiliki desain OO yang sangat baik. Itu tidak selalu buruk, tetapi seperti semua bau itu akan membuat saya berhenti dan mengevaluasi kembali. Ini mengisyaratkan bahwa Anda mungkin dapat membuat desain OO yang lebih baik, atau mungkin Anda harus pergi ke arah lain dan menghindari OO sepenuhnya untuk masalah ini.
sumber
Saya biasa bolak-balik antara kelas dengan banyak metode statis dan tunggal. Keduanya memecahkan masalah, tetapi singleton dapat dengan mudah diganti dengan lebih dari satu. (Pemrogram selalu tampak begitu yakin bahwa hanya akan ada 1 dari sesuatu dan saya menemukan diri saya cukup sering salah untuk sepenuhnya menyerah pada metode statis kecuali dalam beberapa kasus yang sangat terbatas).
Bagaimanapun, singleton memberi Anda kemampuan untuk meneruskan sesuatu ke pabrik nanti untuk mendapatkan contoh yang berbeda dan yang mengubah perilaku seluruh program Anda tanpa refactoring. Mengubah kelas global metode statis menjadi sesuatu dengan data "dukungan" yang berbeda atau perilaku yang sedikit berbeda (kelas anak) adalah masalah besar.
Dan metode statis tidak memiliki keunggulan serupa.
Jadi ya, mereka jahat.
sumber
Selama keadaan internal tidak ikut bermain, ini bagus. Perhatikan bahwa biasanya metode statis diharapkan aman untuk thread, jadi jika Anda menggunakan struktur data helper, gunakan metode tersebut dengan cara yang aman untuk thread.
sumber
Jika Anda tahu Anda tidak perlu menggunakan kondisi internal C, tidak apa-apa. Namun, jika itu berubah di masa depan, Anda harus membuat metode ini non-statis. Jika non-statis untuk memulai, Anda bisa mengabaikan status internal jika Anda tidak membutuhkannya.
sumber
Jika ini adalah metode utilitas, sebaiknya buat statis. Guava dan Apache Commons dibangun berdasarkan prinsip ini.
Pendapat saya tentang ini murni pragmatis. Jika ini adalah kode aplikasi Anda, metode statis umumnya bukan yang terbaik untuk dimiliki. Metode statis memiliki batasan pengujian unit yang serius - metode tersebut tidak dapat dengan mudah dipermainkan: Anda tidak dapat memasukkan fungsionalitas statis yang dibuat-buat ke beberapa pengujian lainnya. Anda juga biasanya tidak dapat memasukkan fungsionalitas ke dalam metode statis.
Jadi dalam logika aplikasi saya, saya biasanya memiliki panggilan metode kecil seperti utilitas statis. Yaitu
salah satu keuntungannya adalah saya tidak menguji metode seperti itu :-)
sumber
Ya, tidak ada peluru perak tentunya. Kelas statis baik untuk utilitas / pembantu kecil. Tetapi menggunakan metode statis untuk pemrograman logika bisnis tentu saja jahat. Perhatikan kode berikut
Anda melihat panggilan metode statis ke
ItemsProcessor.SplitItem(newItem);
Penyebab bauBusinessService
mengisolasinyaItemsProcessor
(sebagian besar alat pengujian tidak meniru kelas statis) dan pengujian unit tidak mungkin dilakukan. Tidak Ada Tes Unit == kualitas rendahsumber
Metode statis umumnya merupakan pilihan yang buruk bahkan untuk kode tanpa negara. Alih-alih, buat kelas tunggal dengan metode ini yang dibuat instance-nya sekali dan dimasukkan ke dalam kelas yang ingin menggunakan metode tersebut. Kelas semacam itu lebih mudah untuk diejek dan diuji. Mereka jauh lebih berorientasi pada objek. Anda dapat membungkusnya dengan proxy saat diperlukan. Statika membuat OO lebih sulit dan saya tidak melihat alasan untuk menggunakannya di hampir semua kasus. Tidak 100% tapi hampir semuanya.
sumber