Cara menandai kelas sebagai sedang dikembangkan di Jawa

12

Saya sedang mengerjakan proyek magang, tetapi saya harus pergi sebelum saya bisa menyelesaikan semuanya.

Saya memiliki 1 kelas yang tidak cukup stabil untuk penggunaan produksi. Saya ingin menandai / menandai kelas ini sehingga orang lain tidak akan sengaja menggunakannya dalam produksi. Saya sudah menaruh pemberitahuan di Javadoc, tapi itu sepertinya tidak cukup. Beberapa kesalahan atau peringatan kompiler akan lebih baik.

Kode diatur seperti ini:

[Package] | company.foo.bar.myproject
          |-- Class1.java
          |-- Class2.java
          |-- Class3.java <--(not stable)

Jika ada kelas pabrik tunggal yang memanggil orang-orang kelas dalam metode umum, saya bisa mengatur metode untuk class3sebagai private. Namun API TIDAK terkena seperti itu. Pengguna akan langsung menggunakan kelas itu, misalnya new Class1();, tetapi saya tidak bisa membuat kelas tingkat atas pribadi. Apa praktik terbaik untuk menghadapi situasi ini?

Wei Shi
sumber
1
Apa yang Anda maksud dengan "API tidak diekspos melalui metode?" Apakah kelas ini dimaksudkan untuk digunakan melalui API Refleksi?
Tom G
5
Kesalahan kompiler? Mengapa tidak melempar pengecualian pada konstruktor saja?
Mchl
Maaf bila membingungkan. Saya telah mengedit posting saya.
Wei Shi
1
Anda tidak bisa membuat kelas menjadi privat, tetapi Anda bisa menjadikan konstruktornya pribadi.
Peter Taylor

Jawaban:

15

Mengapa tidak memeriksa semua kelas yang tidak stabil ke cabang lain di sistem kontrol versi Anda?

Andrew Moss
sumber
2
Menurut saya ini akan 'menyembunyikan' kode. Bagaimana jika kodenya hampir melakukan apa yang orang lain perlu lakukan dengan beberapa perubahan kecil. Jika Anda meletakkannya di cabang mereka mungkin tidak akan pernah melihatnya dan hanya akan mengimplementasikan kembali semuanya.
c_maker
3
@c_maker: Memberitahu orang lain bahwa cabang ada dan apa yang ada di dalamnya harus menjadi bagian dari apa yang diteruskan ketika dia pergi.
Blrfl
2
@Birlf Jika dia khawatir orang lain tidak melihat penjelasan di JavaDoc tentang kode yang mereka gunakan, saya ragu mereka akan mencari dokumentasi lain yang dia hasilkan.
KeithB
Kekhawatiran saya adalah bahwa fitur ini masih berkembang, tetapi master scrum memilih untuk mengesampingkannya dengan alasan apa pun (moratorium yang memblokir pengujian E2E, dalam kasus kami). Jika kita tidak bergabung untuk menguasainya, mungkin ada banyak pekerjaan gabungan di ujung jalan. Kami baru saja menjadikan c`tor pribadi, dan memberi anotasi pada kelas @Experimental, seperti di Spark
Joey Baruch
11

Jika Anda telah mengomentari kelas dengan benar, Anda dapat menandai bit fungsionalitas yang tidak lengkap sebagai "usang" dan atau berkomentar keluar nyali dari metode dan menempatkan a throw new UnsupportedOperationException();.

Lihat Apakah ada sesuatu seperti .NET's NotImplementedException di Java? untuk detail.

Heath Lilley
sumber
2
Ini adalah cara defacto menangani hit hit karena saya mengerti hal
Martijn Verburg
4

Saya tidak tahu peringatan kompiler seperti itu.

Dalam situasi Anda, saya mungkin akan menggunakan @Deprecatedanotasi. Ini akan mencoret panggilan metode sehingga akan jelas bagi yang lain bahwa ada sesuatu yang terjadi. Ketika mereka melihat apa yang terjadi, mereka akan melihat komentar Anda tentang 'belum siap produksi' dan pergi AHA.

c_maker
sumber
2
pemanggilan metode hanya dicoret jika IDE mendukungnya.
FrustratedWithFormsDesigner
5
Benar, tetapi kebanyakan orang mungkin akan menggunakan salah satu IDE yang mendukungnya.
c_maker
3

Saya tidak berpikir ada cara standar menandai kode sebagai WIP, Incomplete, atau sesuatu seperti itu.

Anda bisa membuat pengecualian baru bernama ClassUnstableExceptiondan kemudian menaikkannya di Class3konstruktor dengan pesan yang menjelaskan bagaimana mereka seharusnya tidak menggunakannya. Ini buruk, karena hanya memperingatkan mereka pada saat run time.

Anda juga dapat mencoba membuat kelas tidak dapat disamakan dalam beberapa cara, dan kemudian menambahkan catatan ke bagian kode yang membuat kompiler sehingga jika seseorang pergi untuk memperbaiki kode mereka semoga akan melihat penjelasan mengapa mereka tidak boleh menggunakan kelas itu . Ini mungkin tidak berfungsi jika mereka menggunakan beberapa alat "memperbaiki masalah" semi-otomatis yang dimiliki beberapa IDE. Ini juga buruk karena bisa merusak bangunan.

Anda bisa membuat anotasi bernama WIP(karena yang terdekat saya bisa pikirkan adalah Deprecatedtetapi itu tidak benar-benar berarti hal yang sama) dan menggunakannya untuk membubuhi keterangan kelas. Ini mungkin akan menjadi pekerjaan yang sedikit lebih, dan apa yang akan mendukung anotasi?

Akhirnya, Anda bisa memasukkannya ke dalam komentar, tetapi itu hanya akan berhasil jika orang benar-benar membacanya .

EDIT:

Ini mungkin relevan: Bagaimana cara sengaja menyebabkan pesan peringatan kompiler java kustom?

FrustratedWithFormsDesigner
sumber
melempar pengecualian membuat gerhana mengeluh tentang kode yang tidak terjangkau. Ada solusi?
Wei Shi
@ Usavich: Tidak yakin karena saya belum melihat kode, tapi mungkin itu juga bisa membantu mencegah pengembang di masa depan menggunakan kode?
FrustratedWithFormsDesigner
@Usavich: Lihat tautan yang saya tambahkan di EDIT dalam posting saya, ini pertanyaan serupa di mana OP ingin menambahkan peringatan kompiler khusus. Mungkin bisa membantu Anda menambahkan anotasi "UnstableCode" khusus.
FrustratedWithFormsDesigner
3

Mengapa itu ada di tempat pertama?

Anda telah memeriksa kode yang tidak stabil ke dalam jalur utama? Mengapa?

Kode yang tidak stabil tidak boleh diperiksa ke dalam trunk / main / master atau apa pun nama trunk utama. Ini dianggap sebagai pengembangan berisiko tinggi dan seharusnya disisihkan di cabang sendiri tempat Anda bekerja alih-alih diperiksa ke utama.

Saya sangat mendorong Anda (dan pimpinan tim Anda) untuk membaca Strategi Cabang SCM Lanjutan . Secara khusus, perhatikan peran pengembangan dan apa yang dikatakannya tentang apa yang dianggap sebagai pengembangan berisiko tinggi:

Secara umum, pertimbangkan untuk menggunakan cabang terpisah untuk setiap proyek berisiko tinggi. Proyek-proyek berisiko tinggi dicirikan oleh ukuran besar, jumlah besar orang, materi pelajaran yang tidak dikenal, materi pelajaran yang sangat teknis, garis waktu yang sangat ketat, tanggal pengiriman yang tidak pasti, persyaratan yang tidak lengkap atau tidak stabil, dan tim proyek yang didistribusikan secara geografis. Demikian pula, pertimbangkan untuk menunjuk cabang tunggal untuk pengembangan risiko rendah di setiap rilis. Beberapa sumber termasuk [WING98] merekomendasikan penggunaan garis utama untuk tujuan ini. Pertimbangkan faktor-faktor yang dibahas di atas untuk jalur utama sebelum melakukan tindakan ini. Pengembangan risiko rendah mungkin memiliki kebijakan berbeda dari garis utama bahkan jika Anda memiliki banyak anggota keluarga produk yang berkoordinasi melalui jalur utama.

Membiarkan orang memeriksa kode yang tidak stabil (atau tidak digunakan) ke dalam jalur utama berarti Anda akan membingungkan upaya pengembangan di masa depan tentang upaya mempertahankan kode ini. Setiap cabang dan klon dari perwakilan dari sekarang sampai akhir waktu akan mengandung ini sampai seseorang mengatakan "codenya mati" dan menghapusnya.

Ada beberapa yang mengatakan "baik, jika di cabang itu akan dilupakan" dan sementara itu mungkin benar, setelah lupa kode mati (dan tidak stabil) di garis utama sering kali lebih buruk karena membingungkan semua pengembangan masa depan sampai dihapus - dan maka itu bahkan lebih dilupakan. Cabang "/ fooProject / branch / WeisBigIdea" (atau yang setara) yang terlihat bagus terlihat dan lebih mudah untuk dikerjakan di masa mendatang - terutama jika jenisnya berfungsi.

@Deprecated

Hal pertama adalah @Deprecatedanotasi. Ini melampaui javadoc dan memuntahkan peringatan kompiler. javacmemberikan -deprecationbendera yang digambarkan sebagai:

Perlihatkan deskripsi setiap penggunaan atau timpa anggota atau kelas yang sudah usang. Tanpa -deprecation, javacmenunjukkan ringkasan file sumber yang menggunakan atau menimpa anggota atau kelas yang sudah tidak digunakan. -deprecation adalah singkatan untuk -Xlint:deprecation.

Sebagaimana dicatat, ini melampaui peringatan kompiler standar.

Dalam banyak IDE, metode dan nilai yang usang ditampilkan dengan coretan:

foo.bar();

Dan akan menghasilkan output seperti:

$ javac -Xlint:all Foo.java Bar.java
Bar.java:2: warning: [deprecation] Foo in unnamed package has been deprecated
interface Bar extends Foo { }
                      ^

Bergantung pada struktur bangunan Anda, Anda mungkin memiliki peringatan untuk membatalkan pembangunan. Ini hanya akan merusak build jika salah satu kelas Anda digunakan (tidak hanya jika dikompilasi).

@CustomAnnotation

Ada banyak pendekatan untuk ini. Misalnya, javac @Warning annotation Lightweight yang menyediakan prosesor anotasi yang mengeluarkan peringatan pada waktu kompilasi ketika sesuatu dengan anotasi itu digunakan ( tutorial netbeans tentang prosesor anotasi khusus sehingga Anda bisa mendapatkan gambaran tentang apa yang terjadi di balik adegan).

Oracle bahkan menggambarkan contoh penggunaan anotasi khusus untuk @Unfinishedanotasi dalam Memanfaatkan Metadata Java, Bagian 2: Anotasi Kustom .

Dengan AnnotationProcessor , Anda dapat menjalankan kode arbitrer pada waktu kompilasi. Ini benar-benar terserah Anda untuk memutuskan apa yang ingin Anda lakukan. Peringatkan, hancurkan bangunan ketika sesuatu digunakan. Ada banyak tutorial di luar sana di web tentang cara menulis kode semacam ini. Apakah Anda ingin membuat kesalahan ketika dikompilasi (ini akan mengganggu dan menyebabkannya dihapus) atau jika digunakan (cukup sedikit lebih kompleks untuk ditulis).

Perhatikan bahwa semua ini berarti mengubah build untuk benar-benar menggunakan prosesor anotasi.


sumber
2

Anda dapat memperkenalkan pemrosesan anotasi waktu kompilasi tetapi ini akan memaksa semua anggota tim untuk menyesuaikan proses kompilasi mereka.

Namun saya menemukan seluruh proses sedikit membingungkan. API yang tidak stabil harus dipisahkan dengan jelas dengan membuat cabang di sistem kontrol versi Anda. Jika itu benar-benar harus di sisa basis kode, telah didokumentasikan sebagai tidak stabil dan tetap digunakan masalahnya tidak benar-benar teknis tetapi terletak di dalam organisasi dan komunikasi. Ya, Anda dapat memperkenalkan verifikasi teknis (seperti pemrosesan anotasi) tetapi itu tidak akan menyelesaikan masalah - cukup pindahkan ke tingkat lain.

Jadi rekomendasi saya adalah: Jika Anda tidak dapat memisahkan basis kode dengan meletakkannya di cabang yang berbeda maka bicaralah dengan orang-orang dan jelaskan kepada mereka mengapa mereka tidak boleh menggunakan API.

perdian
sumber
0

Bisakah Anda memindahkan semua kelas yang tidak lengkap ke subpackage bernama sesuatu yang jelas seperti "NOTCOMPLETE"? Ini sedikit hack tetapi mungkin cukup terlihat.

(Jika mereka tidak semuanya dalam paket yang sama, Anda dapat membuat ulang struktur paket di bawah sana.)

Alex Feinman
sumber
0

Saya tidak tahu bahwa sebenarnya ada cara yang baik untuk melakukan ini dalam kode. Ambil satu langkah mundur:

Buat dua salinan dari keseluruhan proyek, satu dengan kelas, dan satu tanpa. Tandai versi tanpa kelas sebagai basis kode stabil, siap untuk rilis produksi, dan versi dengan kelas sebagai pengembangan untuk rilis di masa depan. Dokumentasikan apa yang perlu terjadi sebelum kelas ini dapat dianggap berkualitas produksi.

Idealnya, Anda harus melakukan ini menggunakan cabang dalam solusi kontrol sumber pilihan Anda. Anda mungkin harus sedikit curang, karena sepertinya Anda belum menggunakan strategi percabangan seperti itu. Hapus kelas baru dengan hati-hati, periksa dalam versi tanpa itu, dan lakukan beberapa pengujian regresi. Ketika Anda puas itu stabil, Anda bisa menandai revisi itu, membuat cabang pengembangan dari tag, dan kemudian menambahkan kelas kembali di cabang pengembangan.

Adam Jaskiewicz
sumber
0

Saya akan memilih untuk membuat abstrak kelas, dan berkomentar dengan tepat - dengan cara itu, kode tersebut masih ada untuk referensi, tetapi semoga berhasil bagi siapa saja yang mencoba untuk membuat instance :)

Phil Lello
sumber
-1

Bagaimana dengan membuat ketergantungan yang tidak bisa diselesaikan oleh kompiler? Cukup tambahkan:

impor this.is.not.done.yet.do.not.use.it;

ke atas. Pengguna tidak akan dapat mengompilasinya.

Jika Anda ingin menguji kelas, cukup buat paket / kelas dengan nama itu (atau gunakan yang lebih sederhana seperti "experimental.danger") dan Anda dapat menguji kode baru.

Neal Tibrewala
sumber
1
Kompilasi akan gagal bahkan jika saya tidak menggunakannya ... ide buruk ...
Silviu Burcea