Fitur opsional: metode default atau antarmuka terpisah

8

Antarmuka khusus tampaknya menjadi cara yang baik untuk mengekspos fitur opsional dalam hierarki jenis khusus domain. Namun, mereka menghambat penggunaan dekorator dan pola komposit, yang juga umum dalam hierarki semacam ini.

Terutama, mungkin tidak ada yang ingin mengimplementasikan dekorator / komposit untuk setiap kemungkinan kombinasi antarmuka ini, jadi lebih sering mereka mengimplementasikan semua antarmuka opsional dan menggunakan pengecekan tipe untuk meneruskan panggilan secara selektif, yang mengalahkan tujuan memiliki antarmuka yang terpisah.

Alternatif, yang menggunakan kerangka kerja Java Collection, adalah untuk memasukkan semua operasi dalam tipe dasar dan mengisinya dengan implementasi dummy. Metode default di Java 8 lebih lanjut memfasilitasi penggunaan ini.

Di satu sisi, ini terasa seperti perdebatan kolom nullable di dunia basis data. Apakah ada argumen yang kuat terhadap pendekatan yang lebih praktis?

billc.cn
sumber
Apakah Anda terbatas pada Java atau JVM? Karena Scala menyelesaikan masalah ini dengan rapi
Frank
@Jujur saya bermimpi untuk dapat menggunakan Scala atau bahasa apa pun yang memiliki sifat, tapi sayangnya, menggunakan Java 8 sudah merupakan lompatan besar bagi perusahaan saya ...
billc.cn

Jawaban:

2

Salah satu solusi untuk masalah ini yang saya gunakan di masa lalu (di mana sejumlah besar dekorator menambah fasilitas ke basis yang relatif sederhana, dengan banyak kemungkinan antarmuka) adalah memiliki kelas dasar untuk dekorator dan kelas yang mereka bungkus, terlepas dari antarmuka yang mereka implementasikan, yang memiliki metode yang dideklarasikan (menggunakan sintaksis Java):

    public <T> T findImplementation (Class<T> cls) {
       if (cls.isAssignableFrom(getClass())
           return cls.cast(this);
      return wrapped.findImplementation (cls);
   }

Jelas implementasi non-dekorator mengembalikan null daripada meneruskan permintaan, karena tidak ada tempat untuk meneruskannya dalam kasus ini.

Jules
sumber
Solusi yang sangat menarik. (Saya akhirnya menambahkan getWrappedInstance()metode ke hierarki tipe saya untuk melakukan sesuatu yang serupa. Berharap saya telah memikirkan hal ini.)
billc.cn
1

Tantangan dengan alternatifnya adalah membuat penambahan / perubahan / penghapusan fitur opsional lebih sulit. Sebagai contoh, jika kita menambahkan fitur opsional baru, kita sekarang harus mengubah kelas dasar, dan kemudian mengubah semua subclass untuk menambahkan fitur atau non-fitur. Ini dapat agak dikurangi jika ada default yang wajar, seperti no-op, jadi hanya subtipe yang mendukung fitur yang perlu mengganti bagian yang diperlukan. Jika fitur opsional ini sedikit, relatif stabil, dan tidak mungkin berubah, cukup menambahkannya ke supertype sudah cukup. Jika tidak, maka pemeliharaan dapat mulai menjadi sulit.

Pola desain yang paling umum untuk memulihkan tipe dari supertype adalah pola pengunjung . Ini mungkin rumit dalam situasi Anda karena satu objek dapat mengimplementasikan beberapa antarmuka, tetapi masih bisa dilakukan dengan beberapa modifikasi.

cbojar
sumber