Beberapa bulan yang lalu saya mulai bekerja di proyek baru, dan ketika melalui kode itu membuat saya jumlah metode statis yang digunakan. Tidak hanya metode utilitas collectionToCsvString(Collection<E> elements)
, tetapi juga banyak logika bisnis disimpan di dalamnya.
Ketika saya bertanya kepada orang yang bertanggung jawab untuk alasan di balik ini, dia mengatakan itu adalah cara untuk melarikan diri dari tirani Spring . Ada sesuatu di sekitar proses berpikir ini: untuk menerapkan metode pembuatan tanda terima pelanggan, kami dapat memiliki layanan
@Service
public class CustomerReceiptCreationService {
public CustomerReceipt createReceipt(Object... args) {
CustomerReceipt receipt = new CustomerReceipt();
// creation logic
return receipt;
}
}
Sekarang, pria itu mengatakan bahwa dia tidak suka memiliki kelas yang dikelola secara tidak perlu oleh Spring, pada dasarnya karena memberlakukan batasan bahwa kelas klien haruslah kacang Spring sendiri. Kami akhirnya memiliki segalanya yang dikelola oleh Spring, yang cukup banyak memaksa kami untuk bekerja dengan objek stateless dengan cara prosedural. Kurang lebih apa yang dinyatakan di sini https://www.javacodegeeks.com/2011/02/domain-driven-design-spring-aspectj.html
Jadi alih-alih kode di atas, dia punya
public class CustomerReceiptCreator {
public static CustomerReceipt createReceipt(Object... args) {
CustomerReceipt receipt = new CustomerReceipt();
// creation logic
return receipt;
}
}
Saya bisa berdebat sampai menghindari Spring mengelola kelas kami jika memungkinkan, tetapi apa yang saya tidak lihat adalah manfaat dari memiliki semuanya yang statis. Metode statis ini juga stateless, jadi juga tidak terlalu OO. Saya akan merasa lebih nyaman dengan sesuatu
new CustomerReceiptCreator().createReceipt()
Dia mengklaim bahwa metode statis memiliki beberapa manfaat tambahan. Yaitu:
- Lebih mudah dibaca. Impor metode statis dan kita hanya perlu peduli dengan tindakan, tidak ada kelas apa yang melakukannya.
- Jelas merupakan metode yang bebas dari panggilan DB, jadi kinerja-bijaksana murah; dan itu adalah hal yang baik untuk membuatnya jelas, sehingga klien potensial perlu masuk ke kode dan memeriksa itu.
- Lebih mudah menulis tes.
Tapi saya hanya merasa ada sesuatu yang tidak sepenuhnya benar dengan ini, jadi saya ingin mendengar beberapa pengembang berpengalaman tentang hal ini.
Jadi pertanyaan saya adalah, apa potensi jebakan dari cara pemrograman ini?
sumber
static
metode yang Anda menggambarkan di atas hanya sebuah metode pabrik biasa. Membuat metode pabrik statis adalah konvensi yang diterima secara umum, karena sejumlah alasan kuat. Apakah metode pabrik sesuai di sini adalah masalah yang berbeda.Jawaban:
Apa perbedaan antara
new CustomerReceiptCreator().createReceipt()
danCustomerReceiptCreator.createReceipt()
? Cukup banyak. Satu-satunya perbedaan signifikan adalah bahwa kasus pertama memiliki sintaks yang jauh lebih canggung. Jika Anda mengikuti yang pertama dengan keyakinan bahwa entah bagaimana menghindari metode statis membuat kode Anda lebih baik OO, Anda salah besar. Membuat objek hanya untuk memanggil metode tunggal di atasnya adalah metode statis dengan sintaks tumpul.Di mana hal-hal menjadi berbeda adalah ketika Anda menyuntikkan
CustomerReceiptCreator
bukannyanew
ing itu. Mari kita pertimbangkan sebuah contoh:Mari kita bandingkan ini versi metode statis:
Keuntungan dari versi statis adalah bahwa saya dapat dengan mudah memberi tahu Anda bagaimana ia berinteraksi dengan seluruh sistem. Tidak. Jika saya belum menggunakan variabel global, saya tahu bahwa sisa dari sistem entah bagaimana belum diubah. Saya tahu bahwa tidak ada bagian lain dari sistem yang mungkin mempengaruhi penerimaan di sini. Jika saya telah menggunakan objek yang tidak dapat diubah, saya tahu bahwa pesanan tidak berubah, dan createReceipt adalah fungsi murni. Dalam hal ini, saya dapat dengan bebas memindahkan / menghapus / etc panggilan ini tanpa khawatir tentang efek acak yang tidak terduga di tempat lain.
Saya tidak bisa membuat jaminan yang sama jika saya menyuntikkan
CustomerReceiptCreator
. Mungkin memiliki kondisi internal yang diubah oleh panggilan, saya mungkin terpengaruh atau mengubah status lainnya. Mungkin ada hubungan yang tak terduga antara pernyataan dalam fungsi saya sehingga mengubah urutan akan menghasilkan bug yang mengejutkan.Di sisi lain, apa yang terjadi jika
CustomerReceiptCreator
tiba-tiba membutuhkan ketergantungan baru? Katakanlah itu perlu memeriksa bendera fitur. Jika kami menyuntikkan, kami dapat melakukan sesuatu seperti:Kemudian kita selesai, karena kode panggilan akan disuntikkan dengan
CustomerReceiptCreator
yang secara otomatis akan disuntikkan aFeatureFlags
.Bagaimana jika kami menggunakan metode statis?
Tapi tunggu! kode panggilan juga perlu diperbarui:
Tentu saja, ini masih menyisakan pertanyaan dari mana
processOrder
mendapatkannyaFeatureFlags
. Jika kita beruntung, jejak berakhir di sini, jika tidak, perlunya melewati FeatureFlags didorong lebih jauh ke atas tumpukan.Ada pertukaran di sini. Metode statis yang secara eksplisit mewariskan dependensi yang menghasilkan lebih banyak pekerjaan. Metode injeksi mengurangi pekerjaan, tetapi membuat dependensi tersirat dan dengan demikian disembunyikan membuat kode lebih sulit untuk dipikirkan.
sumber