1. Pengenalan
Dalam tutorial ringkas ini, kita akan belajar mengenai antara muka penanda di Java.
2. Antara Muka Penanda
Antaramuka penanda adalah antara muka yang tidak mempunyai kaedah atau pemalar di dalamnya . Ia memberikan maklumat jenis run-time mengenai objek , jadi penyusun dan JVM mempunyai maklumat tambahan mengenai objek tersebut .
Antara muka penanda juga dipanggil antara muka penandaan.
Walaupun antarmuka penanda masih digunakan, mereka mungkin menunjukkan bau kod dan harus digunakan dengan teliti. Sebab utama untuk ini adalah bahawa mereka mengaburkan garis mengenai apa yang ditunjukkan oleh antara muka kerana penanda tidak menentukan tingkah laku apa pun. Perkembangan yang lebih baru menyokong anotasi untuk menyelesaikan beberapa masalah yang sama.
3. Antara muka Penanda JDK
Java mempunyai banyak antara muka penanda terbina dalam, seperti Serializable , Cloneable , dan Remote.
Mari kita ambil contoh antara muka Cloneable . Sekiranya kita cuba mengklon objek yang tidak melaksanakan antara muka ini, JVM melemparkan CloneNotSupportedException . Oleh itu, antara muka penanda Cloneable adalah petunjuk kepada JVM yang boleh kita panggil kaedah Object.clone () .
Dengan cara yang sama, ketika memanggil kaedah ObjectOutputStream.writeObject () , JVM memeriksa apakah objek tersebut menggunakan antara muka penanda Serializable . Apabila tidak berlaku, NotSerializableException dilemparkan. Oleh itu, objek tidak bersiri ke aliran output.
4. Antaramuka Penanda Custom
Mari buat antara muka penanda kita sendiri.
Sebagai contoh, kita dapat membuat penanda yang menunjukkan sama ada objek dapat dikeluarkan dari pangkalan data:
public interface Deletable { }
Untuk menghapus entiti dari pangkalan data, objek yang mewakili entiti ini harus melaksanakan antara muka penanda Deletable kami :
public class Entity implements Deletable { // implementation details }
Katakan bahawa kita mempunyai objek DAO dengan kaedah untuk membuang entiti dari pangkalan data. Kita boleh menulis kaedah delete () sehingga hanya objek yang melaksanakan interface marker kita yang dapat dihapus:
public class ShapeDao { // other dao methods public boolean delete(Object object) { if (!(object instanceof Deletable)) { return false; } // delete implementation details return true; } }
Seperti yang dapat kita lihat, kita memberi petunjuk kepada JVM, mengenai tingkah laku runtime objek kita. Sekiranya objek mengimplementasikan antara muka penanda kami, objek tersebut dapat dihapus dari pangkalan data.
5. Antara Muka Penanda vs Anotasi
Dengan memperkenalkan anotasi, Java telah memberi kita alternatif untuk mencapai hasil yang sama dengan antara muka penanda. Lebih-lebih lagi, seperti antara muka penanda, kita dapat menerapkan anotasi ke kelas mana pun, dan kita dapat menggunakannya sebagai petunjuk untuk melakukan tindakan tertentu.
Jadi apa perbezaan utama?
Tidak seperti anotasi, antara muka membolehkan kita memanfaatkan polimorfisme . Hasilnya, kita dapat menambahkan sekatan tambahan pada antara muka penanda.
Sebagai contoh, mari kita tambahkan sekatan bahawa hanya jenis Bentuk yang dapat dikeluarkan dari pangkalan data:
public interface Shape { double getArea(); double getCircumference(); }
Dalam kes ini, antara muka penanda kami, mari kita sebut sebagai DeletableShape, akan kelihatan seperti berikut:
public interface DeletableShape extends Shape { }
Kemudian kelas kami akan melaksanakan antara muka penanda:
public class Rectangle implements DeletableShape { // implementation details }
Oleh itu, semua pelaksanaan DeletableShape juga merupakan implementasi Shape . Jelas, kita tidak dapat melakukannya dengan menggunakan anotasi .
Walau bagaimanapun, setiap keputusan reka bentuk mempunyai pertukaran dan polimorfisme dapat digunakan sebagai hujah balas terhadap antara muka penanda. Dalam contoh kami, setiap kelas yang memperluas Rectangle secara automatik akan melaksanakan DeletableShape.
6. Antaramuka Marker vs Antaramuka Khas
Pada contoh sebelumnya, kita boleh mendapatkan hasil yang sama dengan mengubah kaedah delete () DAO kita untuk menguji sama ada objek kita adalah Shape atau tidak , bukannya menguji apakah itu Deletable:
public class ShapeDao { // other dao methods public boolean delete(Object object) { if (!(object instanceof Shape)) { return false; } // delete implementation details return true; } }
Jadi mengapa membuat antara muka penanda apabila kita dapat mencapai hasil yang sama menggunakan antara muka biasa?
Mari kita bayangkan bahawa, selain jenis Shape , kita juga mahu mengeluarkan jenis Orang dari pangkalan data. Dalam kes ini, terdapat dua pilihan untuk mencapainya:
Pilihan pertama adalah dengan menambahkan cek tambahan ke kaedah delete () kami sebelumnya untuk mengesahkan sama ada objek yang akan dihapus itu adalah contoh Person atau tidak.
public boolean delete(Object object) { if (!(object instanceof Shape || object instanceof Person)) { return false; } // delete implementation details return true; }
Tetapi bagaimana jika kita mempunyai lebih banyak jenis yang ingin kita hapus dari pangkalan data juga? Jelas, ini bukan pilihan yang baik kerana kita harus mengubah kaedah kita untuk setiap jenis baru .
Pilihan kedua adalah untuk membuat yang Orang jenis melaksanakan bentuk antara muka , yang bertindak sebagai antara muka penanda. Tetapi adakah objek Orang itu benar-benar Bentuk ? Jawapannya jelas tidak, dan itu menjadikan pilihan kedua lebih buruk daripada yang pertama.
Oleh itu, walaupun kita dapat mencapai hasil yang sama dengan menggunakan antara muka khas sebagai penanda, kita akan mempunyai reka bentuk yang buruk.
7. Kesimpulannya
Dalam artikel ini, kami membincangkan apakah antara muka penanda dan bagaimana ia dapat digunakan. Kemudian kami melihat beberapa contoh Java bawaan antara muka jenis ini dan bagaimana ia digunakan oleh JDK.
Seterusnya, kami membuat antara muka penanda kami sendiri dan tidak menggunakan anotasi. Akhirnya, kami akhirnya melihat mengapa menjadi amalan yang baik untuk menggunakan antara muka penanda dalam beberapa senario dan bukannya antara muka tradisional.
Seperti biasa, kodnya boleh didapati di GitHub.