Apa pola masalah khas yang mendapat manfaat dari kode yang dirancang untuk menggunakan banyak pewarisan berganda?
Ini hanya satu contoh tapi saya rasa sangat berharga untuk meningkatkan keselamatan dan mengurangi godaan untuk menerapkan perubahan cascading di seluruh penelepon atau subkelas.
Di mana saya telah menemukan banyak pewarisan yang sangat berguna bahkan untuk antarmuka yang paling abstrak dan stateless adalah idiom antarmuka non-virtual (NVI) dalam C ++.
Mereka bahkan tidak benar - benar abstrak kelas dasar seperti antarmuka yang hanya memiliki sedikit implementasi bagi mereka untuk menegakkan aspek universal dari kontrak mereka, karena mereka tidak benar-benar mempersempit generalitas kontrak sehingga lebih baik menegakkannya .
Contoh sederhana (beberapa orang mungkin memeriksa apakah suatu pegangan file yang lewat terbuka atau semacamnya):
// Non-virtual interface (public methods are nonvirtual/final).
// Since these are modeling the concept of "interface", not ABC,
// multiple will often be inherited ("implemented") by a subclass.
class SomeInterface
{
public:
// Pre: x should always be greater than or equal to zero.
void f(int x) /*final*/
{
// Make sure x is actually greater than or equal to zero
// to meet the necessary pre-conditions of this function.
assert(x >= 0);
// Call the overridden function in the subtype.
f_impl(x);
}
protected:
// Overridden by a boatload of subtypes which implement
// this non-virtual interface.
virtual void f_impl(int x) = 0;
};
Dalam hal ini, mungkin f
disebut oleh seribu tempat dalam basis kode, sementara f_impl
ditimpa oleh seratus subclass.
Akan sulit untuk melakukan pemeriksaan keamanan semacam ini di semua 1000 tempat yang memanggil f
atau semua 100 tempat yang mengesampingkan f_impl
.
Dengan hanya membuat titik entri ini ke fungsionalitas nonvirtual, itu memberi saya satu tempat sentral untuk melakukan pemeriksaan ini. Dan pemeriksaan ini tidak mengurangi abstraksi sedikit pun, karena hanya menyatakan prasyarat yang diperlukan untuk memanggil fungsi ini. Dalam arti tertentu, ini bisa saja memperkuat kontrak yang disediakan oleh antarmuka, dan menghilangkan beban memeriksa x
input untuk memastikan itu sesuai dengan prasyarat yang valid di semua 100 tempat yang menimpanya.
Ini adalah sesuatu yang saya harap setiap bahasa miliki, dan juga saya harapkan, bahkan dalam C ++, bahwa itu sedikit lebih merupakan konsep asli (mis: tidak mengharuskan kita untuk mendefinisikan fungsi terpisah untuk menimpanya).
Ini sangat berguna jika Anda tidak melakukan ini assert
sebelumnya, dan menyadari bahwa Anda membutuhkannya nanti ketika beberapa tempat acak dalam basis kode menemukan nilai negatif yang diteruskan f
.