Penamaan antarmuka di Java [ditutup]

324

Sebagian besar bahasa OO mengawali nama antarmuka mereka dengan huruf besar I, mengapa Java tidak melakukan ini? Apa alasan untuk tidak mengikuti konvensi ini?

Untuk menunjukkan apa yang saya maksud, jika saya ingin memiliki antarmuka pengguna dan implementasi pengguna saya akan memiliki dua pilihan di Jawa:

  1. Class = Pengguna, Antarmuka = ​​UserInterface
  2. Class = UserImpl, Interface = Pengguna

Di mana di sebagian besar bahasa:

Kelas = Pengguna, Antarmuka = ​​IUser

Sekarang, Anda mungkin berpendapat bahwa Anda selalu dapat memilih nama yang paling deskriptif untuk implementasi pengguna dan masalahnya hilang, tetapi Java mendorong pendekatan POJO untuk berbagai hal dan sebagian besar wadah IOC menggunakan DynamicProxies secara luas. Kedua hal ini bersama-sama berarti bahwa Anda akan memiliki banyak antarmuka dengan implementasi POJO tunggal.

Jadi, saya kira pertanyaan saya bermuara pada: "Apakah layak mengikuti konvensi penamaan Antarmuka yang lebih luas terutama mengingat kemana arah Java Frameworks menuju?"

Allain Lalonde
sumber
61
"Di mana di sebagian besar bahasa"? Bahasa apa selain bahasa .Net?
wds
2
Komunitas bahasa yang berbeda memiliki konvensi penamaan yang berbeda, dan ini telah berlaku untuk waktu yang sangat lama. Mencari tahu bagaimana konvensi penamaan berasal kadang-kadang pada dasarnya adalah penelitian cerita rakyat.
David Thornley
4
Eclipse adalah pencilan signifikan yang menggunakan Java dengan penamaan gaya IFoo. wiki.eclipse.org/Naming_Conventions
David Leonard
2
Jika Anda melihat pada nama-nama Antarmuka di Android SDK (Java juga), Anda akan melihat bahwa mereka menggunakan konvensi memiliki kata Interface pada akhir sebuah nama interface, seperti NetworkInterface, DialogInterface, dll
sandalone
21
Bagaimana pertanyaan ini bisa "ditutup sebagai tidak konstruktif" ketika itu begitu populer dan menarik bagi begitu banyak orang?
inor

Jawaban:

329

Saya lebih suka tidak menggunakan awalan pada antarmuka:

  • Awalan menyakitkan keterbacaan.

  • Menggunakan antarmuka pada klien adalah cara terbaik standar untuk memprogram, sehingga nama antarmuka harus sesingkat dan senyaman mungkin. Kelas implementasi harus lebih buruk untuk mencegah penggunaannya.

  • Ketika mengubah dari kelas abstrak ke antarmuka konvensi pengkodean dengan awalan saya menyiratkan penggantian nama semua kejadian kelas --- tidak baik!

starblue
sumber
12
Setuju. Satu lagi kunci untuk mengetik jika Anda menggunakan pelengkapan otomatis. Banyak file dimulai dengan I.
Kalecser
85
Setiap IDE yang layak membuat mudah mengubah kode dengan cara yang Anda gambarkan. Juga, ketika mengubah dari kelas abstrak ke antarmuka, saya cukup yakin klien Anda perlu melakukan kompilasi ulang.
Allain Lalonde
63
Sangat terlambat di sini, tetapi: Tidak masalah sama sekali jika IDE membuat mengubah nama sesuatu menjadi mudah. Kode yang menggunakan instance dari beberapa tipe seharusnya tidak pernah peduli apakah tipe itu adalah antarmuka atau kelas atau apa. Dengan demikian, mengekspos detail seperti itu atas nama tipe tidak ada gunanya dan berbahaya untuk dipahami. Jenis dan kontrak yang diungkapkan adalah yang penting!
ColinD
11
Selain itu, jika Anda menuju rute IFoo, bukankah seharusnya CFoo untuk implementasi dan tentu saja pada kegagalan suatu metode akan melempar EFoo.
Robin
57
"Awalan menyakitkan keterbacaan" adalah murni subjektif. Seperti kebanyakan konvensi penamaan. Lebih penting bahwa tim Anda sepakat tentang apa yang harus dilakukan sehingga basis kode konsisten.
dreadwail
121

Apakah memang ada perbedaan antara:

class User implements IUser

dan

class UserImpl implements User

jika semua yang kita bicarakan adalah penamaan konvensi?

Secara pribadi saya lebih suka TIDAK mendahului antarmuka dengan Ikarena saya ingin menjadi pengkodean ke antarmuka dan saya menganggap itu lebih penting dalam hal konvensi penamaan. Jika Anda memanggil antarmuka IUsermaka setiap konsumen kelas itu perlu tahu itu IUser. Jika Anda memanggil kelas UserImplmaka hanya kelas dan wadah DI Anda yang tahu tentang Implbagian tersebut dan konsumen hanya tahu mereka bekerja dengan a User.

Kemudian lagi, saat-saat saya terpaksa menggunakan Implkarena nama yang lebih baik tidak muncul dengan sendirinya sudah sangat sedikit karena implementasi diberi nama sesuai dengan implementasi karena di situlah penting, misalnya

class DbBasedAccountDAO implements AccountDAO
class InMemoryAccountDAO implements AccountDAO
tddmonkey
sumber
Saya pikir Anda ingin tahu itu DAO karena itu menggambarkan fungsi umum tanpa perlu membuka kelas. Jika saya melihat melalui file kelas dalam suatu proyek itu mudah untuk melihat semua DAO dengan mencari * DAO
Patrick
6
DAO adalah pola yang terkenal untuk akses basis data, sehingga memiliki pola pada namanya membuatnya mudah untuk mengetahui apa yang dikerjakan kelas hanya dengan melihat namanya. PS Akan lebih baik untuk mengikuti notasi unta secara ketat ("AccountDao") seperti di mina.apache.org/changes-between-2x-and-1x.html
Esko
4
@ penanda, tidak seperti memiliki I untuk menunjukkan antarmuka. DAO memberi tahu Anda bahwa kelas atau antarmuka adalah objek untuk mengakses data akun, yang dilakukan oleh objek. Memiliki Saya memberitahu Anda yang interface, yang tidak ada hubungannya dengan objek itu sendiri tetapi semantik bahasa
tddmonkey
Saat Anda menyajikannya, awalan vs sufiks.
Andrei Rînea
3
@Andrei: Tidak, ini semantik ("DAO") vs dekorasi yang tidak perlu dari artefak bahasa ("I" seperti dalam antarmuka; fakta, yang disebutkan dalam kode tetap "antarmuka IFoo ...")
Dirk
75

Mungkin ada beberapa alasan Java umumnya tidak menggunakan konvensi IUser.

  1. Bagian dari pendekatan Berorientasi Objek adalah bahwa Anda tidak harus tahu apakah klien menggunakan antarmuka atau kelas implementasi. Jadi, walaupun List adalah sebuah antarmuka dan String adalah kelas yang sebenarnya, sebuah metode dapat dilewati keduanya - tidak masuk akal untuk secara visual membedakan antarmuka.

  2. Secara umum, kita sebenarnya akan lebih suka menggunakan antarmuka dalam kode klien (misalnya, Daftar ke ArrayList). Jadi tidak masuk akal untuk membuat antarmuka yang menonjol sebagai pengecualian.

  3. Konvensi penamaan Java lebih memilih nama yang lebih panjang dengan arti sebenarnya dari awalan gaya Hongaria. Sehingga kode itu akan terbaca mungkin: Daftar mewakili daftar, dan Pengguna mewakili pengguna - bukan IUser.

Avi
sumber
72

Ada juga konvensi lain, yang digunakan oleh banyak proyek open source termasuk Spring.

interface User {
}

class DefaultUser implements User {
}

class AnotherClassOfUser implements User {
}

Saya pribadi tidak suka awalan "Saya" karena alasan sederhana bahwa ini merupakan konvensi opsional. Jadi jika saya mengadopsi ini apakah IIOPConnection berarti antarmuka untuk IOPConnection? Bagaimana jika kelas tidak memiliki awalan "Aku", kemudian aku tahu itu bukan antarmuka .. jawabannya di sini adalah tidak, karena konvensi tidak selalu diikuti, dan pemolisian mereka akan menciptakan lebih banyak pekerjaan yang disimpan oleh konvensi itu sendiri.

ng.
sumber
Saya suka ini, karena ini juga membantu Anda dalam mode menggunakan antarmuka untuk ketergantungan eksternal daripada menggabungkan kelas.
Matt Briggs
47

Seperti yang dikatakan poster lain, biasanya lebih baik memiliki antarmuka yang menentukan kemampuan bukan tipe. Saya cenderung untuk tidak "mengimplementasikan" sesuatu seperti "Pengguna," dan inilah mengapa "IUser" sering tidak benar-benar diperlukan dengan cara yang dijelaskan di sini. Saya sering melihat kelas sebagai kata benda dan antarmuka sebagai kata sifat:

class Number implements Comparable{...}  
class MyThread implements Runnable{...}
class SessionData implements Serializable{....}

Terkadang kata sifat tidak masuk akal, tapi saya masih akan menggunakan antarmuka untuk memodelkan perilaku, tindakan, kemampuan, properti, dll, ... bukan tipe.

Juga, Jika Anda benar-benar hanya akan membuat satu Pengguna dan menyebutnya Pengguna lalu apa gunanya memiliki antarmuka IUser? Dan jika Anda akan memiliki beberapa jenis pengguna yang berbeda yang perlu mengimplementasikan antarmuka umum, apa yang menambahkan "Aku" ke antarmuka menghemat Anda dalam memilih nama implementasi?

Saya pikir contoh yang lebih realistis adalah bahwa beberapa jenis pengguna harus dapat masuk ke API tertentu. Kita dapat mendefinisikan antarmuka Login, dan kemudian memiliki kelas induk "Pengguna" dengan SuperUser, DefaultUser, AdminUser, AdministrativeContact, dll suclasses, beberapa di antaranya akan atau tidak akan mengimplementasikan antarmuka Login (Loginable?) Sesuai kebutuhan.

nairbv
sumber
Saya pikir contoh yang Anda berikan untuk mendukung "antarmuka sebagai kata sifat" miring, karena antarmuka tersebut dimaksudkan untuk lebih seperti campuran (atau sifat). Dengan demikian, antarmuka baik untuk kata sifat dan kata benda - tetapi mungkin tidak untuk indefinite transitive verbs 8 ^ P
Stevel
Ini mungkin berubah dalam beberapa tahun terakhir. Dokumen oracle. memungkinkan antarmuka sebagai tipe: [tautan] docs.oracle.com/javase/tutorial/java/IandI/interfaceAsType.html
karlihnos
38

Bob Lee berkata sekali dalam sebuah presentasi:

apa gunanya antarmuka jika Anda hanya memiliki satu implementasi.

jadi, Anda memulai dengan satu implementasi yaitu tanpa antarmuka. nanti Anda memutuskan, well, ada kebutuhan untuk antarmuka di sini, jadi Anda mengubah kelas Anda menjadi antarmuka.

maka itu menjadi jelas: kelas asli Anda disebut Pengguna. antarmuka Anda sekarang disebut Pengguna. mungkin Anda memiliki UserProdImpl dan UserTestImpl. jika Anda mendesain aplikasi dengan baik, setiap kelas (kecuali yang instantiate Pengguna) tidak akan berubah dan tidak akan melihat bahwa tiba-tiba mereka dapat melewati sebuah antarmuka.

jadi semakin jelas -> Antarmuka Pengguna implementasi UserImpl.

Andreas Petersson
sumber
18
Menggunakan antarmuka akan membantu Test Driven Development. Kami telah mengalami banyak masalah tanpa Domain Model dan pengujian karena kami memutuskan untuk TIDAK menggunakan antarmuka. Seorang teman saya pernah mengutip: "Semuanya adalah antarmuka, itu akan menyelamatkan Anda dalam jangka panjang."
hooknc
4
Mengejek dan dukungan proxy yang mudah. Saya yakin ada alasan lain untuk menyediakan antarmuka juga.
MetroidFan2002
3
Seperti yang baru-baru ini saya katakan kepada seorang kolega, tidak ada biaya untuk memperkenalkan antarmuka sekarang tetapi dapat menghemat banyak waktu nanti.
tddmonkey
2
Jika Anda mungkin memiliki implementasi lain dalam waktu dekat-menengah, antarmuka akan menjadi nilai tambah.
Stef
3
Saya tidak suka argumen "Saya mungkin perlu alat lain di masa depan". Saya lebih suka pendekatan YAGNI: jangan merencanakan untuk hal-hal yang belum terjadi.
David Lavender
24

Dalam C # itu

public class AdminForumUser : UserBase, IUser

Jawa akan mengatakan

public class AdminForumUser extends User implements ForumUserInterface

Karena itu, saya tidak berpikir konvensi hampir sama pentingnya dalam java untuk antarmuka, karena ada perbedaan eksplisit antara warisan dan implementasi antarmuka. Saya akan mengatakan hanya memilih konvensi penamaan yang Anda inginkan, selama Anda konsisten dan menggunakan sesuatu untuk menunjukkan kepada orang-orang bahwa ini adalah antarmuka. Belum selesai java dalam beberapa tahun, tetapi semua antarmuka hanya akan berada di direktori mereka sendiri, dan itu adalah konvensi. Tidak pernah benar-benar memiliki masalah dengannya.

Matt Briggs
sumber
22
Mungkin aku Java coder yang buruk, tapi aku lebih suka gaya C #, berarti semua antarmuka diawali dengan awalan 'I' :)
davs
7
Saya tidak yakin dari mana Anda dan orang lain mendapatkan konvensi ini. Itu tidak terbukti di perpustakaan Java ...
ChiefTwoPencils
6

Dalam pengalaman saya, konvensi "I" berlaku untuk antarmuka yang dimaksudkan untuk memberikan kontrak ke kelas, terutama ketika antarmuka itu sendiri bukan gagasan abstrak kelas.

Misalnya, dalam kasus Anda, saya hanya berharap untuk melihat IUserapakah satu-satunya pengguna yang ingin Anda miliki adalah User. Jika Anda berencana untuk memiliki berbagai jenis pengguna - NoviceUser,, ExpertUserdll. - Saya berharap untuk melihat Userantarmuka (dan, mungkin, AbstractUserkelas yang mengimplementasikan beberapa fungsi umum, seperti get/setName()).

Saya juga harapkan interface yang mendefinisikan kemampuan - Comparable, Iterable, dll - diberi nama seperti itu, dan tidak seperti IComparableatau IIterable.

David Koelle
sumber
Jika satu-satunya pengguna yang ingin Anda miliki adalah Pengguna, mengapa tidak menggunakan Pengguna saja, bukan antarmuka?
Carighan
3
Dalam beberapa arsitektur klien / server, sisi klien perlu mengetahui antarmuka tanpa perlu implementasi server kelas berat.
David Koelle
5

Mengikuti prinsip-prinsip OO yang baik, kode Anda harus (sejauh mungkin / praktis) bergantung pada abstraksi daripada kelas konkret. Sebagai contoh, umumnya lebih baik menulis metode seperti ini:

public void doSomething(Collection someStuff) {
    ...
}

dari ini:

public void doSomething(Vector someStuff) {
    ...
}

Jika Anda mengikuti ide ini, maka saya berpendapat bahwa kode Anda akan lebih mudah dibaca jika Anda memberikan nama antarmuka seperti "Pengguna" dan "BankAccount" (misalnya), daripada "IUser", "UserInterface", atau variasi lainnya.

Satu-satunya bit kode yang harus peduli dengan kelas beton yang sebenarnya adalah tempat di mana kelas beton dibangun. Segala sesuatu yang lain harus ditulis menggunakan antarmuka.

Jika Anda melakukan ini, maka nama kelas beton "jelek" seperti "UserImpl" harus disembunyikan dengan aman dari sisa kode, yang dapat terus menggunakan nama antarmuka "bagus".

KarstenF
sumber
Tapi mengapa repot-repot membuat antarmuka yang cocok untuk setiap kelas di program Anda ketika Anda hanya membutuhkan antarmuka untuk satu atau dua hal?
LegendLength
3

= v = Awalan "I" juga digunakan dalam kerangka kerja Wicket, di mana saya terbiasa dengan cepat. Secara umum, saya menyambut setiap konvensi yang mempersingkat nama kelas Java yang tidak praktis. Ini merepotkan, bagaimanapun, bahwa semuanya diurutkan berdasarkan abjad di bawah "I" di direktori dan di Javadoc.

Praktek pengkodean gawang mirip dengan Swing, di mana banyak instance kontrol / widget dibangun sebagai kelas dalam anonim dengan deklarasi metode inline. Yang menjengkelkan, ini berbeda 180 ° dari Swing dalam Swing yang menggunakan awalan ("J") untuk kelas implementasi.

Sufiks "Impl" adalah singkatan yang sangat kecil dan tidak bisa digunakan secara internasional. Kalau saja kita setidaknya pergi dengan "Imp" itu akan lebih manis (dan lebih pendek). "Impl" digunakan untuk IOC, terutama Spring, jadi kami agak terjebak dengannya untuk saat ini. Itu mendapat sedikit schizo mengikuti 3 konvensi berbeda dalam tiga bagian berbeda dari satu basis kode, meskipun.

Jym Dyer
sumber
0

Apakah ini konvensi penamaan yang lebih luas dalam arti sebenarnya? Saya lebih pada sisi C ++, dan tidak benar-benar di Jawa dan keturunan. Berapa banyak komunitas bahasa yang menggunakan konvensi I?

Jika Anda memiliki konvensi penamaan standar toko yang tidak menggunakan bahasa di sini, gunakan saja. Jika tidak, ikuti konvensi penamaan bahasa.

David Thornley
sumber