Saya baru-baru ini melakukan refactoring proyek berukuran sedang di Jawa untuk kembali dan menambahkan tes unit. Ketika saya menyadari betapa sakitnya mengejek para lajang dan statika, saya akhirnya "mendapatkan" apa yang telah saya baca tentang mereka selama ini. (Saya salah satu dari orang-orang yang perlu belajar dari pengalaman. Oh well.)
Jadi, sekarang saya menggunakan Spring untuk membuat objek dan menyambungkannya ke sekitar, saya menyingkirkan static
kata kunci kiri dan kanan. (Jika saya berpotensi ingin mengejeknya, itu tidak benar-benar statis dalam arti yang sama dengan Math.abs () adalah, kan?) Masalahnya adalah, saya sudah terbiasa menggunakan static
untuk menunjukkan bahwa suatu metode tidak mengandalkan pada keadaan objek apa pun. Sebagai contoh:
//Before
import com.thirdparty.ThirdPartyLibrary.Thingy;
public class ThirdPartyLibraryWrapper {
public static Thingy newThingy(InputType input) {
new Thingy.Builder().withInput(input).alwaysFrobnicate().build();
}
}
//called as...
ThirdPartyLibraryWrapper.newThingy(input);
//After
public class ThirdPartyFactory {
public Thingy newThingy(InputType input) {
new Thingy.Builder().withInput(input).alwaysFrobnicate().build();
}
}
//called as...
thirdPartyFactoryInstance.newThingy(input);
Jadi, di sinilah ia menjadi sensitif. Saya menyukai cara lama karena huruf kapital mengatakan kepada saya bahwa, sama seperti Math.sin (x), ThirdPartyLibraryWrapper.newThingy (x) melakukan hal yang sama dengan cara yang sama setiap kali. Tidak ada status objek untuk mengubah bagaimana objek melakukan apa yang saya minta. Berikut adalah beberapa kemungkinan jawaban yang saya pertimbangkan.
- Tidak ada orang lain yang merasakan hal ini sehingga ada yang salah dengan saya. Mungkin saya belum benar-benar menginternalisasi cara OO dalam melakukan sesuatu! Mungkin saya menulis di Jawa tetapi berpikir dalam FORTRAN atau semacamnya. (Yang akan mengesankan karena saya belum pernah menulis FORTRAN.)
- Mungkin saya menggunakan staticness sebagai semacam proksi untuk imutabilitas untuk keperluan penalaran tentang kode. Yang sedang berkata, petunjuk apa yang harus saya miliki dalam kode saya untuk seseorang yang datang untuk mempertahankannya untuk mengetahui apa yang stateful dan apa yang tidak?
- Mungkin ini harus datang secara gratis jika saya memilih metafora objek yang bagus? misalnya
thingyWrapper
tidak terdengar seperti itu memiliki keadaan bebas dari bungkusnyaThingy
yang mungkin dapat berubah. Demikian pula,thingyFactory
suara seperti itu harus kekal tetapi bisa memiliki strategi berbeda yang dipilih di antara pada saat penciptaan.
Menurut pendapat saya apa yang Anda katakan - semua fungsi statis menjadi nullipotent - adalah cara OO yang baik dalam menulis kode dalam banyak kasus, tetapi saya tidak percaya bahwa ketika Anda melihat fungsi statis, Anda harus secara otomatis menganggap bahwa itu tidak memiliki efek samping . Situasinya mungkin lebih kompleks; mengambil contoh fungsi
Class.forName(String)
yang tampaknya stateless tetapi sebenarnya memuat kelas ke dalam memori dan akhirnya instantiates bidang statis / jalankan penginisialisasi statis; ini adalah contoh fungsi idempoten (panggilan akhirnya setelah yang pertama tidak membuat perbedaan) tetapi ini bukan fungsi murni (tidak dapat dikatakan tidak memiliki efek samping). Ini juga merupakan pilihan yang baik, tetapi mungkin ada kasus di mana tiga panggilan berbeda ke fungsi yang sama menghasilkan tiga hasil yang berbeda; misalnya jika Anda meneleponThread.currentThread()
dalam aplikasi multi-utas tidak ada jaminan Anda akan menerima utas yang sama setiap saat.Solusi yang tepat adalah mendokumentasikan (Javadoc misalnya); juga, dari nama fungsi dan dari apa yang dilakukannya terkadang dapat disimpulkan bahwa fungsi statis adalah fungsi murni. Misalnya, tidak ada alasan bagi seseorang untuk percaya bahwa
Assert.assertTrue(boolean)
dari JUnit akan mengubah keadaan di suatu tempat. Di sisi lain ketika fungsi sepertiSystem.clearProperty(String)
dipanggil, cukup jelas bahwa akan ada efek samping.sumber
Anda dapat membuatnya statis. FxCop di dunia C # akan mendorong Anda untuk membuat hal-hal statis yang tidak ada variabel anggota referensi. Ini adalah hal yang benar untuk dilakukan (biasanya).
Memindahkan mereka semua ke instance mungkin bukan pendekatan yang tepat. Sebaliknya, pisahkan ketergantungan pada metode statis dari kelas yang menggunakannya. Anda dapat menguji metode statis secara terpisah, dan kemudian mengganti ketergantungan pada konsumen ketika mereka perlu diuji.
sumber