Apakah praktik yang buruk memiliki antarmuka untuk mendefinisikan konstanta?

40

Saya menulis satu set kelas tes junit di Jawa. Ada beberapa konstanta, misalnya string yang akan saya butuhkan di kelas tes yang berbeda. Saya berpikir tentang antarmuka yang mendefinisikan mereka dan setiap kelas tes akan mengimplementasikannya.

Manfaat yang saya lihat ada:

  • akses mudah ke konstanta: MY_CONSTANTalih-alihThatClass.MY_CONSTANT
  • setiap konstanta didefinisikan hanya sekali

Apakah pendekatan ini lebih baik atau buruk? Saya merasa sedikit menyalahgunakan konsep antarmuka.

Anda dapat menjawab secara umum tentang antarmuka / konstanta, tetapi juga tentang tes unit jika ada sesuatu yang istimewa tentangnya.

FabianB
sumber
Jawaban untuk "Ini adalah praktik yang buruk untuk memiliki antarmuka mendefinisikan X?", Menjadi X apa pun yang bukan "tanda tangan metode", hampir selalu pasti "Ya".
T. Sar - Reinstate Monica

Jawaban:

79

Joshua Bloch menyarankan hal ini dalam bukunya, Java Efektif :

Bahwa kelas menggunakan beberapa konstanta secara internal adalah detail implementasi. Menerapkan antarmuka konstan menyebabkan detail implementasi ini bocor ke kelas yang diekspor API. Tidak ada konsekuensi bagi pengguna kelas bahwa kelas mengimplementasikan antarmuka konstan. Bahkan, itu mungkin membingungkan mereka. Lebih buruk lagi, ini merepresentasikan komitmen: jika dalam rilis yang akan datang kelas dimodifikasi sehingga tidak perlu lagi menggunakan konstanta, ia masih harus mengimplementasikan antarmuka untuk memastikan kompatibilitas biner.

Anda bisa mendapatkan efek yang sama dengan kelas normal yang mendefinisikan konstanta, lalu gunakan import static com.example.Constants.*;

matt
sumber
13

Dalam kasus kami, kami melakukan ini karena nilai konstanta mewakili kontrak untuk status akhir yang harus disediakan oleh implementasi layanan. Menempatkan konstanta-konstanta ini di antarmuka menentukan status akhir sebagai bagian dari kontrak, dan jika ada implementasi antarmuka yang tidak menggunakannya, itu tidak akan melakukan tugasnya.

Konstanta TERKADANG adalah detail implementasi. KARENA mereka tidak. Seperti biasa, seorang insinyur perlu menggunakan otaknya untuk memutuskan apa yang harus dilakukan, dan tidak bergantung pada pola atau praktik penyapuan.

pengguna144901
sumber
7

Saya tidak berpikir itu hal yang baik untuk memiliki antarmuka hanya untuk konstanta.

Tetapi jika antarmuka yang mendefinisikan perilaku (metode yang mengimplementasikan kelas harus diimplementasikan), memiliki konstanta, tidak apa-apa. Jika "bocor detail implementor" ke API, itu karena itu memang seharusnya. Mereka juga membocorkan bahwa implementor mengimplementasikan metode foo dan bar.

Ambil contoh antarmuka java.awt.Transparency. Ini memiliki konstanta OPAQUE, BITMASK dan TRANSLUCENT tetapi juga memiliki metode getTransparency ().

Jika perancang meletakkan konstanta-konstanta itu di sana karena dia pikir itu akan cukup stabil untuk menjadi bagian dari antarmuka, seperti getTransparency ().

Tulains Córdova
sumber
2

Berpikir itu adalah sudut pandang yang sebagian besar populer di tempat-tempat di mana desain dengan kontrak berlaku.
Antarmuka adalah kontrak. Menempatkan konstanta dalam antarmuka berarti setiap kelas yang mematuhi kontrak menyetujui nilai / konsep yang diidentifikasi oleh konstanta.

CMR
sumber
1
antarmuka adalah kontrak publik. VALUES Konstan adalah masalah pribadi, antarmuka publik paling banyak harus memaparkan nama mereka. Yang terbaik diserahkan kepada kelas abstrak.
jwenting
Contoh kasus: javax.naming.Context, javax.ims.Session, dan ratusan antarmuka seperti itu ...
CMR
2
@jwenting Juga, bisakah antarmuka publik "at most expose their names", tanpa mengekspos nilai-nilai?
CMR
itu tergantung pada bahasa pemrograman saya kira. Dalam kasus Jawa, no.
jwenting
2

Sebuah perusahaan tempat saya bekerja menggunakan konstanta yang diimpor antarmuka 1 . Saya tidak merasa ada ruginya.

Pertanyaan yang harus Anda tanyakan pada diri sendiri adalah, seberapa pentingkah namespacing bagi Anda? Dalam kasus konstanta, itu benar-benar semua kelas bertindak sebagai. Jika Anda memiliki ribuan konstanta, Anda mungkin tidak ingin semua konstanta itu selalu tersedia.

Yang paling keren tentang antarmuka adalah memberi Anda keuntungan dari bekerja dengan cara apa pun - membawa semua ruang nama yang Anda butuhkan, atau tidak satupun dari mereka (dan mengaksesnya secara eksplisit, dengan MyInterface.CONSTANT). Hampir sama import static MyInterface.*, tetapi sedikit lebih jelas.


1: Jika Anda tidak terbiasa dengan Java, maksud saya bukan importkata kunci, maksud saya dibawa masukimplements MyConstantsInterface

Nicole
sumber
1

Saya berasal dari latar belakang yang sebagian besar dipengaruhi terutama oleh 'Ada cara' dan '. Bersih.' Saya akan mengatakan tidak, bahwa mungkin tidak terbaik untuk mendeklarasikan konstanta dalam antarmuka. Secara teknis tidak diizinkan dalam c #.

Alasan saya mengatakan tidak adalah bahwa antarmuka adalah bentuk kontrak yang mendefinisikan perilaku, bukan keadaan atau struktur. Konstanta menyiratkan semacam keadaan (primitif), atau aspek keadaan (komposit atau agregat).

Saya dapat menghargai dorongan untuk membuat nilai default dan standar yang tersedia untuk semua orang yang mengimplementasikan antarmuka, tetapi mungkin keadaan default akan lebih baik dijelaskan dalam objek atau template abstrak atau nilai, di mana default akan memiliki setidaknya konteks minimal.

Untuk panduan yang lebih teknis: unduh.oracle.com/javase/1.5.0/docs/guide/language/static-import.html

JustinC
sumber
Menambahkan lebih banyak tautan yang mengacu pada Impor Statis (1,5): 1. Wikipedia 2. Oracle Docs referensikan @Justinc
Abhijeet
1
So when should you use static import? Very sparingly! Only use it when you'd otherwise be tempted to declare local copies of constants, or to abuse inheritance (the Constant Interface Antipattern). In other words, use it when you require frequent access to static members from one or two classes. If you overuse the static import feature, it can make your program unreadable and unmaintainable, polluting its namespace with all the static members you import. Referensi dari Oracle Docs
Abhijeet
1

Tidak, ini bukan praktik buruk umum.

Intinya adalah bahwa konstanta seperti artefak lainnya harus dimasukkan di bawah aturan visibilitas minimal dan tingkat abstraksi yang tepat.

Menggunakan sintaks hanya karena Anda bisa adalah masalah sebenarnya.

oopexpert
sumber