Antarmuka Marker di Java

1. Perkenalan

Dalam tutorial singkat ini, kita akan belajar tentang antarmuka marker di Java.

2. Antarmuka Penanda

Antarmuka marker adalah antarmuka yang tidak memiliki metode atau konstanta di dalamnya . Ini menyediakan informasi tipe run-time tentang objek , sehingga compiler dan JVM memiliki informasi tambahan tentang objek .

Antarmuka penanda juga disebut antarmuka penandaan.

Meskipun antarmuka penanda masih digunakan, antarmuka penanda kemungkinan besar mengarah ke bau kode dan harus digunakan dengan hati-hati. Alasan utama untuk ini adalah bahwa mereka mengaburkan garis tentang apa yang diwakili oleh antarmuka karena penanda tidak menentukan perilaku apa pun. Pengembangan yang lebih baru lebih menyukai anotasi untuk memecahkan beberapa masalah yang sama.

3. Antarmuka Penanda JDK

Java memiliki banyak antarmuka penanda bawaan, seperti Serializable , Cloneable , dan Remote.

Mari kita ambil contoh antarmuka Cloneable . Jika kita mencoba untuk menggandakan objek yang tidak mengimplementasikan antarmuka ini, JVM akan menampilkan CloneNotSupportedException . Oleh karena itu, antarmuka marker Cloneable adalah indikator JVM yang dapat kita panggil metode Object.clone () .

Dengan cara yang sama, saat memanggil metode ObjectOutputStream.writeObject () , JVM memeriksa apakah objek mengimplementasikan antarmuka marker Serializable . Jika tidak demikian, NotSerializableException akan muncul. Oleh karena itu, objek tidak diserialkan ke aliran keluaran.

4. Antarmuka Penanda Kustom

Mari buat antarmuka penanda kita sendiri.

Misalnya, kita dapat membuat penanda yang menunjukkan apakah suatu objek dapat dihapus dari database:

public interface Deletable { }

Untuk menghapus entitas dari database, objek yang mewakili entitas ini harus mengimplementasikan antarmuka penanda yang dapat dihapus :

public class Entity implements Deletable { // implementation details }

Katakanlah kita memiliki objek DAO dengan metode untuk menghapus entitas dari database. Kita bisa menulis metode delete () sehingga hanya objek yang mengimplementasikan antarmuka marker kita yang bisa 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 bisa kita lihat, kita memberikan indikasi ke JVM, tentang perilaku runtime objek kita. Jika objek mengimplementasikan antarmuka marker kita, itu bisa dihapus dari database.

5. Antarmuka Penanda vs. Anotasi

Dengan memperkenalkan anotasi, Java telah memberi kita alternatif untuk mencapai hasil yang sama seperti antarmuka marker. Selain itu, seperti antarmuka penanda, kita dapat menerapkan anotasi ke kelas mana pun, dan kita dapat menggunakannya sebagai indikator untuk melakukan tindakan tertentu.

Jadi apa perbedaan utamanya?

Tidak seperti anotasi, antarmuka memungkinkan kita memanfaatkan polimorfisme . Hasilnya, kita dapat menambahkan batasan tambahan ke antarmuka marker.

Misalnya, mari tambahkan batasan bahwa hanya tipe Bentuk yang dapat dihapus dari database:

public interface Shape { double getArea(); double getCircumference(); }

Dalam kasus ini, antarmuka marker kita, sebut saja DeletableShape, akan terlihat seperti berikut:

public interface DeletableShape extends Shape { }

Kemudian kelas kita akan mengimplementasikan antarmuka penanda:

public class Rectangle implements DeletableShape { // implementation details }

Oleh karena itu, semua implementasi DeletableShape juga merupakan implementasi Shape . Jelas, kami tidak dapat melakukannya menggunakan anotasi .

Namun, setiap keputusan desain memiliki trade-off dan polimorfisme dapat digunakan sebagai argumen tandingan terhadap antarmuka penanda. Dalam contoh kami, setiap kelas yang memperluas Rectangle akan secara otomatis mengimplementasikan DeletableShape.

6. Antarmuka Penanda vs. Antarmuka Khas

Dalam contoh sebelumnya, kita bisa mendapatkan hasil yang sama dengan memodifikasi metode delete () DAO untuk menguji apakah objek kita berbentuk Shape atau bukan , alih-alih 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 antarmuka penanda ketika kita dapat mencapai hasil yang sama menggunakan antarmuka biasa?

Mari kita bayangkan bahwa, selain tipe Shape , kami juga ingin menghapus tipe Person dari database. Dalam kasus ini, ada dua opsi untuk mencapainya:

Opsi pertama adalah menambahkan pemeriksaan tambahan ke metode delete () kami sebelumnya untuk memverifikasi apakah objek yang akan dihapus adalah turunan dari Person atau bukan.

public boolean delete(Object object) { if (!(object instanceof Shape || object instanceof Person)) { return false; } // delete implementation details return true; }

Tetapi bagaimana jika kita memiliki lebih banyak tipe yang ingin kita hapus dari database juga? Jelas, ini bukan pilihan yang baik karena kita harus mengubah metode kita untuk setiap tipe baru .

Pilihan kedua adalah untuk membuat para Orang tipe mengimplementasikan Shape antarmuka , yang bertindak sebagai antarmuka penanda. Tapi apakah objek Person benar-benar Shape ? Jawabannya jelas tidak, dan itu membuat pilihan kedua lebih buruk dari yang pertama.

Oleh karena itu, meskipun kita dapat mencapai hasil yang sama dengan menggunakan antarmuka biasa sebagai penanda, kita akan mendapatkan desain yang buruk.

7. Kesimpulan

Pada artikel ini, kita membahas apa itu antarmuka penanda dan bagaimana mereka dapat digunakan. Kemudian kami melihat beberapa contoh Java built-in dari jenis antarmuka ini dan bagaimana mereka digunakan oleh JDK.

Selanjutnya, kami membuat antarmuka penanda kami sendiri dan menimbangnya dengan menggunakan anotasi. Akhirnya, kami akhirnya melihat mengapa praktik yang baik menggunakan antarmuka penanda dalam beberapa skenario, bukan antarmuka tradisional.

Seperti biasa, kode dapat ditemukan di GitHub.