Haruskah nama antarmuka dimulai dengan awalan "I"?

73

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?

Charles Sprayberry
sumber
3
Saya setuju dengan poin Anda. Ada titik di mana terlalu banyak menyembunyikan informasi tidak terlalu membantu. Namun, Sekalipun Anda mengikuti panduan ini, Anda masih dapat mengetahui jenisnya menggunakan IDE atau add-on.
NoChance
3
Pertanyaan ini pada dasarnya dikenal sebagai pertanyaan "Notasi Hongaria", Anda harus menemukan banyak argumen dan alasan mengapa sebagian besar pengembang non-MS meninggalkannya dengan kata kunci ini. Notasi Hungaria sebagian besar lazim untuk variabel, tetapi pada dasarnya sama untuk jenis.
thiton
2
Pengeditan judul sebelumnya sangat buruk. Pertanyaan ini bukan tentang notasi Hongaria secara umum hanya karena ia menyebutkan sebuah konvensi yang mungkin terkait dengannya. Manfaat relatif HN sepenuhnya tidak relevan di sini; pertanyaannya adalah secara khusus tentang antarmuka vs kelas dan apakah perbedaan semantik itu penting / cukup menarik untuk membenarkan konvensi penamaan kasus-khusus.
Aaronaught
Re 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.
david.pfx
Untuk apa nilainya, saya lebih suka awalan "Aku". Saya juga menggunakan awalan "Abstrak" pada kelas abstrak untuk alasan yang sama. Ini tidak membuat perbedaan bagi konsumen kelas / antarmuka, tetapi dapat membuat perbedaan besar bagi mereka yang perlu memberikan contoh itu, dan juga membuatnya lebih mudah bagi pengembang lain yang membaca kode Anda. Ini berarti mereka dapat melihat secara sekilas apa yang mereka hadapi, daripada harus berkonsultasi dengan IDE berdasarkan kasus per kasus untuk informasi lebih lanjut. Saya baru saja mulai menggunakan Angular dan merasa sangat menjengkelkan karena mereka tidak mengikuti konvensi ini!
Dan King

Jawaban:

67

Jika Anda berhenti untuk memikirkannya, Anda akan melihat bahwa antarmuka benar-benar tidak jauh berbeda dari kelas abstrak:

  • Keduanya memiliki metode dan / atau properti (perilaku);
  • Tidak boleh memiliki bidang non-pribadi (data);
  • Tidak ada yang bisa dipakai secara langsung;
  • Berasal dari satu berarti menerapkan metode abstrak yang dimilikinya, kecuali jika jenis turunannya juga abstrak.

Faktanya, perbedaan paling penting antara kelas dan antarmuka adalah:

  • Antarmuka tidak dapat memiliki data pribadi;
  • Anggota antarmuka tidak dapat memiliki pengubah akses (semua anggota adalah "publik");
  • Sebuah kelas dapat mengimplementasikan banyak antarmuka (berbeda dengan umumnya hanya dapat mewarisi dari satu kelas dasar).

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 Ikarena 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.

Aaronaught
sumber
Terima kasih atas gangguan ini. +1 untuk "perbedaan yang berarti antara kelas dan antarmuka ..."
Charles Sprayberry
24
+1 untuk "Semua ini dikatakan, saya cenderung untuk awalan antarmuka C # saya dengan saya karena itu adalah konvensi .NET yang digunakan dan dianjurkan oleh Microsoft". Ini adalah alasan yang cukup bagi saya dalam C #. Dengan mengikuti standar umum ini, kemungkinan besar programmer NET lainnya mengidentifikasi antarmuka.
Robotsushi
4
Sebagai seseorang yang menulis pernyataan Java dan C # "Semua ini dikatakan, saya cenderung untuk awalan antarmuka C # saya dengan saya karena itu adalah konvensi .NET yang digunakan dan dianjurkan oleh Microsoft" tidak dapat dikecilkan - itu adalah salah satu hal yang membantu saya mengingat bahasa tempat saya bekerja,
Aidos
3
Perbedaan lain dalam. NET (tetapi tidak di Jawa) adalah bahwa banyak bahasa .NET tidak memungkinkan antarmuka mengandung metode statis, sehingga meretas Iantarmuka dapat memberikan nama yang bagus bagi kelas untuk memegang metode statis yang terkait dengan antarmuka (misalnya Enumerable<T>.Emptyatau Comparer<T>.Default).
supercat
Saya punya satu masalah. Di C ++ jika Anda membuka tajuk dan melihat bahwa class Foosudah meluas class Bar, tidak segera jelas apakah class Barsedang diperluas atau diterapkan. Jadi sekarang Anda harus pergi dan melihat di class Barheader untuk memutuskan apakah boleh class Foountuk memperpanjang class 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.
jsj
14

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!

Jim Nutt
sumber
2
+1 untuk konsistensi> konvensi. Di C # Anda akan awalan dengan I dan di Java Anda tidak akan. Tugas yang berbeda membutuhkan konvensi yang berbeda
Bringer128
2
+1 sementara saya pribadi lebih suka untuk tidak memiliki Is pada antarmuka saya, karena tidak konsisten dengan perpustakaan BCL dan pihak ke-3 yang digunakan dalam proyek .Net bukan merupakan opsi imho.
jk.
13

Buku ini penuh dengan hal-hal yang baik, tetapi saya masih akan menambahkan "Saya" ke nama antarmuka.

Bayangkan Anda memiliki public interface ILogimplementasi standar public class Log.

Sekarang, jika Anda memutuskan untuk memilikinya public interface Log, tiba-tiba Anda harus mengubah kelas Log ke public class LogDefaultatau 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.

CodeART
sumber
Ini juga disebutkan dalam dokumentasi
levininja
30
"Bayangkan Anda memiliki antarmuka publik ILog dengan implementasi standar kelas publik Log." - Kemudian Anda memiliki nama yang buruk untuk implementasi default Anda. Apa yang Logharus dilakukan Masuk ke konsol? Ke syslog? Ke mana-mana? Mereka harus dipanggil ConsoleLog, SyslogLogdan NullLog, masing-masing. Logbukan nama yang baik untuk kelas beton, karena itu bukan nama konkret.
Sebastian Redl
7
Secara pribadi inilah tepatnya mengapa saya benci melihat ITheClassName, apakah Anda hanya membuat antarmuka tanpa alasan, apakah hanya berisik di atas TheClassName. Jika antarmuka Anda memiliki tujuan, Anda sebaiknya memberikannya nama yang lebih baik daripada ITheClassName
Richard Tingle
Nama kelas digunakan sekali (untuk instantiate), nama antarmuka digunakan di mana-mana. Menambahkan huruf ke antarmuka untuk menyimpan huruf pada nama kelas adalah ekonomi palsu (karakter).
sergut
@ RichardTingle Tapi saya pikir penggunaan umum ada hanya sehingga MyClassmemiliki 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-1 MyClasske IMyClasspemetaan.)
ruffin
8

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.

deadalnix
sumber
@Mat> Ya, itu kesalahan saya, dan saya mengeditnya.
deadalnix
5

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 IMyClassduplikasi yang tidak perlu. Sepertinya Anda tidak akan menulis public 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.

Ela782
sumber
Apakah Anda yakin ini menjawab pertanyaan? Anda mungkin ingin membaca jawaban lain dan mengklarifikasi beberapa poin Anda.
david.pfx
C ++ jelas memiliki antarmuka, bahkan jika tidak ada kata kunci untuk itu. Apa yang Anda sebut kelas di mana setiap fungsi anggota adalah virtual murni dan tidak ada variabel anggota?
@ david.pfx: Saya pikir saya tepat menjawab pertanyaan "Haruskah nama antarmuka dimulai dengan awalan" I "?": Tergantung pada bahasa pemrograman. Jika menurut Anda uraian saya tidak cukup jelas, saya senang memperbaikinya - bagian mana yang tidak jelas untuk Anda?
Ela782
2
@ JohnGaughan: Tentu memiliki antarmuka! Tapi intinya saya adalah tentang kata kunci. C ++ tidak memilikinya, jadi tidak terlihat oleh IDE / pengguna jika dia berurusan dengan antarmuka atau tidak. Namun di Jawa, itu langsung terlihat.
Ela782
1
Baca jawaban peringkat teratas dan bandingkan jawaban Anda. Anda baru mengenal SO, dan ini adalah kesempatan untuk mempelajari jenis jawaban apa yang menarik suara. Seperti berdiri, milikmu tidak akan. Dengan lebih banyak pekerjaan, lebih banyak penjelasan, lebih banyak nilai, itu mungkin saja. Tetap bertahan!
david.pfx
4

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.

Pete
sumber
+1 Ikuti idiom bahasa yang Anda gunakan. Jelas penulis buku adalah pengembang Java. .NET / C #: ILog Java: Log Tetapi kerugiannya: Ketika saya suka memiliki kelas Log yang mengimplementasikan antarmuka ILog .... MyLog, LogDefault, LogBase, ...? Jelek, bukan? Lebih jelek adalah: LogImpl ....: D
hfrmobile
0

Dalam kode (Jawa) saya, saya cenderung memiliki konvensi ini di API yang saya paparkan kepada penelepon:

  • Fungsionalitas disediakan melalui antarmuka, dan tidak pernah oleh kelas.
  • Bagian yang tidak berfungsi adalah kelas.

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.)

Donal Fellows
sumber
Saya juga tidak pernah meletakkan Iawalan di antarmuka. Tentu saja itu sebuah antarmuka! Ada dalam API (atau SPI)!
Donal Fellows