Beberapa orang menyarankan bahwa hal-hal dapat di luar kendali dengan menggunakan teman. Saya setuju, tapi itu tidak mengurangi kegunaannya. Saya tidak yakin bahwa teman tentu saja menyakiti paradigma OO lebih daripada membuat semua anggota kelas Anda publik. Tentu saja bahasa akan memungkinkan Anda untuk membuat semua anggota Anda menjadi publik, tetapi itu adalah programmer yang disiplin yang menghindari jenis pola desain itu. Demikian juga programmer yang disiplin akan menggunakan teman untuk kasus-kasus tertentu yang masuk akal. Saya merasa internal terlalu banyak mengungkapkan dalam beberapa kasus. Mengapa mengekspos kelas atau metode untuk semua yang ada di majelis?
Saya memiliki halaman ASP.NET yang mewarisi halaman dasar saya sendiri, yang pada gilirannya mewarisi System.Web.UI.Page. Di halaman ini, saya memiliki beberapa kode yang menangani pelaporan kesalahan pengguna akhir untuk aplikasi dalam metode yang dilindungi
ReportError("Uh Oh!");
Sekarang, saya memiliki kontrol pengguna yang terdapat di halaman. Saya ingin kontrol pengguna dapat memanggil metode pelaporan kesalahan di halaman.
MyBasePage bp = Page as MyBasePage;
bp.ReportError("Uh Oh");
Tidak dapat melakukannya jika metode ReportError dilindungi. Saya bisa membuatnya internal, tetapi terkena kode apa pun di majelis. Saya hanya ingin itu terkena elemen UI yang merupakan bagian dari halaman saat ini (termasuk kontrol anak). Lebih khusus, saya ingin kelas kontrol basis saya untuk menentukan metode pelaporan kesalahan yang sama persis, dan cukup memanggil metode di halaman dasar.
protected void ReportError(string str) {
MyBasePage bp = Page as MyBasePage;
bp.ReportError(str);
}
Saya percaya bahwa sesuatu seperti teman dapat berguna dan diimplementasikan dalam bahasa tanpa membuat bahasa kurang "OO" seperti, mungkin sebagai atribut, sehingga Anda dapat memiliki kelas atau metode menjadi teman untuk kelas atau metode tertentu, yang memungkinkan pengembang untuk memberikan akses spesifik. Mungkin sesuatu seperti ... (kode semu)
[Friend(B)]
class A {
AMethod() { }
[Friend(C)]
ACMethod() { }
}
class B {
BMethod() { A.AMethod() }
}
class C {
CMethod() { A.ACMethod() }
}
Dalam kasus contoh saya sebelumnya mungkin memiliki sesuatu seperti berikut (orang dapat berdebat semantik, tapi saya hanya mencoba untuk menyampaikan ide):
class BasePage {
[Friend(BaseControl.ReportError(string)]
protected void ReportError(string str) { }
}
class BaseControl {
protected void ReportError(string str) {
MyBasePage bp = Page as MyBasePage;
bp.ReportError(str);
}
}
Seperti yang saya lihat, konsep teman tidak memiliki risiko lebih dari itu daripada membuat sesuatu menjadi publik, atau menciptakan metode atau properti publik untuk mengakses anggota. Jika ada teman yang memungkinkan tingkat rincian aksesibilitas data yang lain dan memungkinkan Anda untuk mempersempit aksesibilitas itu daripada meluaskannya dengan internal atau publik.