Saya telah membaca " Kode Bersih " oleh Robert Martin untuk mudah-mudahan, menjadi programmer yang lebih baik. Meskipun sejauh ini tidak ada yang benar-benar melanggar, itu membuat saya berpikir berbeda tentang cara saya mendesain aplikasi dan menulis kode.
Ada satu bagian dari buku yang saya tidak hanya tidak setuju dengan, tetapi tidak masuk akal bagi saya, khususnya dalam hal konvensi penamaan antarmuka. Ini teksnya, diambil langsung dari buku. Saya telah berani aspek ini saya merasa membingungkan dan ingin klarifikasi.
Saya lebih suka membiarkan antarmuka tanpa hiasan. I yang sebelumnya, yang sangat umum dalam gumpalan warisan hari ini, adalah gangguan terbaik dan terlalu banyak informasi paling buruk. Saya tidak ingin pengguna saya tahu bahwa saya memberi mereka antarmuka .
Mungkin itu karena saya hanya seorang siswa, atau mungkin karena saya belum pernah melakukan pemrograman berbasis profesional atau tim tapi saya ingin pengguna tahu itu adalah antarmuka. Ada perbedaan besar antara mengimplementasikan antarmuka dan memperluas kelas.
Jadi, pertanyaan saya bermuara pada, "Mengapa kita harus menyembunyikan fakta bahwa beberapa bagian dari kode mengharapkan antarmuka?"
Sunting
Menanggapi jawaban:
Jika tipe Anda adalah antarmuka atau kelas adalah bisnis Anda, bukan bisnis seseorang yang menggunakan kode Anda. Jadi Anda tidak boleh membocorkan detail kode Anda dalam kode pihak ketiga ini.
Mengapa saya tidak "membocorkan" detail apakah jenis yang diberikan adalah antarmuka atau kelas ke kode pihak ketiga? Bukankah penting bagi pengembang pihak ketiga menggunakan kode saya untuk mengetahui apakah mereka akan mengimplementasikan antarmuka atau memperluas kelas? Apakah perbedaannya tidak sepenting yang saya pikirkan?
sumber
to know whether they will be implementing an interface or extending a class
: ya, tetapi sebagian besar pengguna kode Anda akan menyebutnya, tidak menerapkan atau memperluasnya, dan mereka benar-benar tidak peduli yang mana.Jawaban:
Jika Anda berhenti untuk memikirkannya, Anda akan melihat bahwa antarmuka benar-benar tidak jauh berbeda dari kelas abstrak:
Faktanya, perbedaan paling penting antara kelas dan antarmuka adalah:
Karena satu-satunya perbedaan bermakna antara kelas dan antarmuka berkisar pada (a) data pribadi dan (b) hirarki jenis - tidak ada yang membuat sedikit perbedaan bagi penelepon - umumnya tidak perlu mengetahui apakah suatu jenis adalah antarmuka atau kelas. Anda tentu tidak membutuhkan indikasi visual .
Namun, ada kasus sudut tertentu yang harus diperhatikan. Khususnya, jika Anda menggunakan refleksi, intersepsi, proksi dinamis / mixin, tenun bytecode, pembuatan kode, atau apa pun yang melibatkan mengacaukan langsung dengan sistem pengetikan atau kode lingkungan itu sendiri - maka itu sangat membantu dan kadang-kadang perlu untuk segera diketahui. bat apakah Anda berurusan dengan antarmuka atau kelas. Anda jelas tidak ingin kode Anda gagal secara misterius karena Anda mencoba menambahkan kelas, bukan antarmuka, sebagai mixin.
Untuk kode logika bisnis umum, vanilla, run-of-the-mill, perbedaan antara kelas abstrak dan antarmuka tidak perlu diiklankan karena mereka tidak akan pernah ikut bermain.
Semua ini dikatakan, saya cenderung untuk awalan antarmuka C # saya
I
karena itu adalah .NET convention yang digunakan dan dianjurkan oleh Microsoft. Dan ketika saya menjelaskan konvensi pengkodean ke pengembang baru, jauh lebih mudah menggunakan aturan Microsoft daripada menjelaskan mengapa kita memiliki aturan "khusus" kita sendiri.sumber
I
antarmuka dapat memberikan nama yang bagus bagi kelas untuk memegang metode statis yang terkait dengan antarmuka (misalnyaEnumerable<T>.Empty
atauComparer<T>.Default
).class Foo
sudah meluasclass Bar
, tidak segera jelas apakahclass Bar
sedang diperluas atau diterapkan. Jadi sekarang Anda harus pergi dan melihat diclass Bar
header untuk memutuskan apakah bolehclass Foo
untuk memperpanjangclass Baz
. Selain itu, awalan I memberikan petunjuk visual yang jelas jika "kelas dasar tunggal" dilanggar atau tidak - sehingga Anda mendapatkan pemeriksaan kewarasan setiap kali Anda membuka header.Dalam banyak hal, konsistensi lebih penting daripada konvensi. Selama Anda konsisten dalam skema penamaan Anda, mereka tidak akan sulit untuk dikerjakan. Awalan antarmuka dengan huruf I jika Anda suka, atau biarkan namanya tanpa hiasan, tidak masalah bagi saya selama Anda memilih gaya dan tetap menggunakannya!
sumber
Buku ini penuh dengan hal-hal yang baik, tetapi saya masih akan menambahkan "Saya" ke nama antarmuka.
Bayangkan Anda memiliki
public interface ILog
implementasi standarpublic class Log
.Sekarang, jika Anda memutuskan untuk memilikinya
public interface Log
, tiba-tiba Anda harus mengubah kelas Log kepublic class LogDefault
atau sesuatu di baris itu. Anda berubah dari memiliki satu karakter tambahan menjadi tujuh - tentu saja itu sia-sia.Seringkali ada garis tipis antara teori dan praktik. Secara teori ini adalah ide yang sangat bagus, tetapi dalam praktiknya itu tidak terlalu baik.
sumber
Log
harus dilakukan Masuk ke konsol? Ke syslog? Ke mana-mana? Mereka harus dipanggilConsoleLog
,SyslogLog
danNullLog
, masing-masing.Log
bukan nama yang baik untuk kelas beton, karena itu bukan nama konkret.MyClass
memiliki variasi yang dapat dipermainkan , kan? Artinya, kita sering menggunakan antarmuka untuk membuat metode publik benar - benar publik dengan cara yang memungkinkan untuk pengujian. (Tidak mengatakan itu baik atau buruk, tetapi memahami bahwa motivasi untuk antarmuka sering hanya untuk membuat kelas yang dependensi mudah dipermainkan memang menjelaskan 1-ke-1MyClass
keIMyClass
pemetaan.)Yah ini bukan tentang mengimplementasikan antarmuka atau memperluas kelas. Dalam kasus ini, Anda tetap tahu apa yang Anda lakukan.
Namun, ketika kode pihak ketiga (modul lain dari aplikasi untuk contoh) memanipulasi data Anda, kode ini seharusnya tidak peduli jika Anda menghadirkan antarmuka atau kelas.
Inilah inti dari abstraksi. Anda mempresentasikan kode pihak ketiga ini objek tipe tertentu. Jenis yang diberikan ini memiliki beberapa fungsi anggota yang dapat Anda hubungi. Cukup.
Jika tipe Anda adalah antarmuka atau kelas adalah bisnis Anda, bukan bisnis seseorang yang menggunakan kode Anda. Jadi Anda tidak boleh membocorkan detail kode Anda ke kode pihak ketiga ini.
Omong-omong, antarmuka dan kelas adalah tipe referensi di bagian akhir. Dan inilah yang penting. Jadi inilah yang harus ditekankan oleh konvensi penamaan Anda.
sumber
Sebagian besar jawaban tampaknya berasumsi bahwa bahasa pemrograman adalah Java atau C # di mana ada konsep (atau kata kunci) untuk antarmuka / kelas abstrak. Dalam kasus-kasus ini, dalam IDE yang layak, segera terlihat dengan jenis kelas yang mana penawaran dan penulisan
public interface IMyClass
duplikasi yang tidak perlu. Sepertinya Anda tidak akan menulispublic final FinalMyClass
- bayangkan menempatkan setiap kata kunci dalam nama kelas.Namun, menurut pendapat saya di C ++ situasinya sedikit berbeda karena kita harus masuk ke file header dan melihat apakah kelas memiliki metode virtual untuk mengetahui apakah itu adalah kelas abstrak. Dalam hal ini, saya dapat dengan jelas melihat argumen untuk menulis
class AbstractMyClass
.Jadi jawaban saya adalah: Tergantung pada bahasa pemrogramannya.
Diperbarui 2016: 2 tahun pengalaman C ++ kemudian saya mungkin akan menganggapnya sebagai praktik buruk untuk mengawali nama kelas
Abstract
, meskipun saya akan mengatakan mungkin ada basis kode yang sangat kompleks sehingga mungkin masuk akal.sumber
Ikuti idiom bahasa yang Anda gunakan.
Setiap bahasa memiliki idiom dan pedoman pengkodean sendiri. Misalnya, dalam C #, itu adalah idiomatis untuk antarmuka awalan dengan I. In Go, tidak.
sumber
Dalam kode (Jawa) saya, saya cenderung memiliki konvensi ini di API yang saya paparkan kepada penelepon:
Secara non-fungsional, maksud saya hal-hal seperti struktur data murni (seperti kelas yang bertindak sebagai jembatan untuk serialisasi XML atau ORM), enumerasi dan pengecualian, yang semuanya tidak dapat berupa antarmuka (well, Anda bisa untuk kelas data murni , tapi itu banyak pekerjaan untuk mendapatkan sangat sedikit karena tidak ada yang kelas lakukan kecuali memegang data).
Dalam hal konvensi penamaan, antarmuka cenderung memetakan ke nomina aktor (misalnya,
FooBarWatcher
) atau kata sifat (misalnya,FooBarWatchable
) dan kelas data dan enumerasi murni memetakan ke nomina yang tidak aktif (misalnya,FooBarStatus
); IDE dapat memandu konsumen API tanpa konvensi penamaan khusus. Pengecualian ikuti biasa konvensi Java (FooBarException
,FooBarError
,FooBarFault
) tentu saja.Saya juga akan sering meletakkan antarmuka dalam paket mereka sendiri atau bahkan di perpustakaan mereka sendiri, hanya untuk memastikan bahwa saya tidak tergoda untuk melanggar aturan saya sendiri. (Ini juga membantu saya mengelola pembuatan ketika saya memperoleh kode dari sumber eksternal seperti dokumen WSDL.)
sumber
I
awalan di antarmuka. Tentu saja itu sebuah antarmuka! Ada dalam API (atau SPI)!