Saya jarang menggunakan antarmuka dan menemukan mereka umum dalam kode orang lain.
Saya juga membuat kelas sub dan super (sambil membuat kelas sendiri) jarang dalam kode saya.
- Apakah itu hal yang buruk?
- Apakah Anda menyarankan mengubah gaya ini?
- Apakah gaya ini memiliki efek samping?
- Apakah ini karena saya belum pernah mengerjakan proyek besar?
programming-practices
coding-style
interfaces
jineesh joseph
sumber
sumber
Jawaban:
Ada beberapa alasan mengapa Anda mungkin ingin menggunakan antarmuka:
http://msdn.microsoft.com/en-us/library/3b5b8ezk(v=vs.80).aspx
Antarmuka seperti hal lain dalam pemrograman. Jika Anda tidak membutuhkannya, jangan menggunakannya. Saya telah melihat mereka digunakan secara luas sebagai masalah gaya, tetapi jika Anda tidak membutuhkan properti dan kemampuan khusus yang disediakan oleh antarmuka, saya tidak melihat manfaat menggunakannya "hanya karena".
sumber
Warisan kelas dan antarmuka keduanya memiliki tempat masing-masing. Warisan berarti "adalah" sementara antarmuka memberikan kontrak yang mendefinisikan seperti apa sesuatu "berperilaku".
Saya akan mengatakan bahwa menggunakan antarmuka lebih sering bukanlah praktik yang buruk sama sekali. Saya sedang membaca "Efektif C # - 50 Cara Tertentu untuk Meningkatkan C #" Anda oleh Bill Wagner. Item nomor 22 menyatakan, dan kutipan saya, "Memilih Menentukan dan Menerapkan Antarmuka ke Warisan".
Secara umum saya menggunakan kelas dasar ketika saya perlu mendefinisikan implementasi spesifik dari perilaku umum antara tipe yang berhubungan secara konseptual. Lebih sering saya menggunakan antarmuka. Bahkan, saya biasanya memulai dengan mendefinisikan antarmuka untuk kelas ketika saya mulai membuat satu ... bahkan jika pada akhirnya saya tidak mengkompilasi antarmuka, saya menemukan bahwa itu membantu untuk memulai dengan mendefinisikan API publik dari kelas dari mulai. Jika saya menemukan bahwa saya memiliki beberapa kelas yang mengimplementasikan antarmuka, dan logika implementasi identik, hanya kemudian saya akan bertanya pada diri sendiri apakah masuk akal untuk mengimplementasikan kelas dasar yang umum di antara kedua tipe tersebut.
Beberapa kutipan dari buku Bill Wagners ...
semua kelas turunan segera menggabungkan perilaku itu. Menambahkan anggota ke antarmuka memecah semua kelas yang mengimplementasikan antarmuka itu. Mereka tidak akan berisi metode baru dan tidak akan lagi dikompilasi. Setiap pelaksana harus memperbarui jenis itu untuk memasukkan anggota baru. Memilih antara kelas dasar abstrak dan antarmuka adalah pertanyaan tentang cara terbaik untuk mendukung abstraksi Anda dari waktu ke waktu. Antarmuka diperbaiki: Anda merilis antarmuka sebagai kontrak untuk serangkaian fungsi yang dapat diterapkan oleh semua jenis. Kelas dasar dapat diperpanjang dari waktu ke waktu. Ekstensi itu menjadi bagian dari setiap kelas turunan. Kedua model dapat dicampur untuk menggunakan kembali kode implementasi sambil mendukung beberapa antarmuka. " Mereka tidak akan berisi metode baru dan tidak akan lagi dikompilasi. Setiap pelaksana harus memperbarui jenis itu untuk memasukkan anggota baru. Memilih antara kelas dasar abstrak dan antarmuka adalah pertanyaan tentang cara terbaik untuk mendukung abstraksi Anda dari waktu ke waktu. Antarmuka diperbaiki: Anda merilis antarmuka sebagai kontrak untuk serangkaian fungsi yang dapat diterapkan oleh semua jenis. Kelas dasar dapat diperpanjang dari waktu ke waktu. Ekstensi itu menjadi bagian dari setiap kelas turunan. Kedua model dapat dicampur untuk menggunakan kembali kode implementasi sambil mendukung beberapa antarmuka. " Mereka tidak akan berisi metode baru dan tidak akan lagi dikompilasi. Setiap pelaksana harus memperbarui jenis itu untuk memasukkan anggota baru. Memilih antara kelas dasar abstrak dan antarmuka adalah pertanyaan tentang cara terbaik untuk mendukung abstraksi Anda dari waktu ke waktu. Antarmuka diperbaiki: Anda merilis antarmuka sebagai kontrak untuk serangkaian fungsi yang dapat diterapkan oleh semua jenis. Kelas dasar dapat diperpanjang dari waktu ke waktu. Ekstensi itu menjadi bagian dari setiap kelas turunan. Kedua model dapat dicampur untuk menggunakan kembali kode implementasi sambil mendukung beberapa antarmuka. " Anda merilis antarmuka sebagai kontrak untuk serangkaian fungsi yang dapat diterapkan oleh semua jenis. Kelas dasar dapat diperpanjang dari waktu ke waktu. Ekstensi itu menjadi bagian dari setiap kelas turunan. Kedua model dapat dicampur untuk menggunakan kembali kode implementasi sambil mendukung beberapa antarmuka. " Anda merilis antarmuka sebagai kontrak untuk serangkaian fungsi yang dapat diterapkan oleh semua jenis. Kelas dasar dapat diperpanjang dari waktu ke waktu. Ekstensi itu menjadi bagian dari setiap kelas turunan. Kedua model dapat dicampur untuk menggunakan kembali kode implementasi sambil mendukung beberapa antarmuka. "
"Antarmuka pengkodean memberikan fleksibilitas yang lebih besar untuk pengembang lain daripada pengkodean ke tipe kelas dasar."
"Menggunakan antarmuka untuk mendefinisikan API untuk suatu kelas memberikan fleksibilitas yang lebih besar."
"Ketika tipe Anda mengekspos properti sebagai tipe kelas, itu mengekspos seluruh antarmuka ke kelas itu. Menggunakan antarmuka, Anda dapat memilih untuk mengekspos hanya metode dan properti yang Anda ingin klien gunakan."
"Kelas dasar menggambarkan dan menerapkan perilaku umum di seluruh jenis beton terkait. Antarmuka menggambarkan potongan-potongan fungsionalitas atom yang dapat diterapkan oleh jenis beton yang tidak terkait. Keduanya memiliki tempat masing-masing. Kelas menentukan jenis yang Anda buat. Antarmuka menggambarkan perilaku jenis-jenis itu sebagai bagian dari fungsionalitas. Jika Anda memahami perbedaannya, Anda akan membuat desain yang lebih ekspresif yang lebih tangguh dalam menghadapi perubahan. Gunakan hierarki kelas untuk mendefinisikan tipe terkait. Paparkan fungsionalitas menggunakan antarmuka yang diimplementasikan pada semua tipe itu. "
sumber
Satu hal yang belum disebutkan adalah pengujian: di semua C # mocking-libraries, dan juga beberapa untuk Java, kelas tidak dapat diejek kecuali mereka mengimplementasikan antarmuka. Hal ini menyebabkan banyak proyek mengikuti praktik Agile / TDD untuk memberikan setiap kelas antarmuka sendiri.
Beberapa orang menganggap praktik terbaik ini, karena "mengurangi kopling," tapi saya tidak setuju - saya pikir itu hanya solusi untuk kekurangan dalam bahasa.
Saya pikir antarmuka paling baik digunakan ketika Anda memiliki dua kelas atau lebih yang, secara abstrak, melakukan "hal yang sama," tetapi dengan cara yang berbeda.
Misalnya, kerangka kerja .Net memiliki beberapa kelas yang menyimpan daftar barang , tetapi mereka semua menyimpan barang itu dengan cara yang berbeda. Jadi, masuk akal untuk memiliki
IList<T>
antarmuka abstrak , yang dapat diimplementasikan menggunakan metode yang berbeda.Anda juga harus menggunakannya ketika Anda ingin 2+ kelas dapat dipertukarkan, atau diganti di masa depan. Jika cara baru menyimpan daftar keluar di masa depan,,
AwesomeList<T>
dengan asumsi Anda menggunakanIList<T>
seluruh kode Anda, mengubahnya dengan menggunakanAwesomeList<T>
berarti hanya mengubah beberapa lusin baris, bukan beberapa ratus / ribu.sumber
Hasil utama dari tidak menggunakan warisan dan antarmuka ketika mereka sesuai adalah kopling ketat . Ini mungkin agak sulit dipelajari untuk dikenali, tetapi biasanya gejala yang paling jelas adalah ketika Anda membuat perubahan, Anda menemukan bahwa Anda sering harus melalui banyak file lain untuk membuat perubahan dalam efek riak.
sumber
Tidak, ini tidak buruk sama sekali. Antarmuka eksplisit harus digunakan, jika dan hanya jika, dua kelas dengan antarmuka umum harus dapat dipertukarkan pada saat run-time. Jika mereka tidak perlu dipertukarkan, maka jangan memilikinya. Sesederhana itu. Warisan rapuh dan harus dihindari sedapat mungkin. Jika Anda dapat menghindarinya atau menggunakan obat generik sebagai gantinya, maka lakukanlah.
Masalahnya adalah, dalam bahasa seperti C # dan Java dengan generik waktu kompilasi yang lemah, Anda dapat akhirnya melanggar KERING karena tidak ada cara untuk menulis satu metode yang dapat menangani lebih dari satu kelas kecuali semua kelas mewarisi dari basis yang sama. C # 4
dynamic
dapat menangani hal ini.Masalahnya, warisan seperti variabel global - begitu Anda menambahkannya dan kode Anda bergantung padanya, Tuhan membantu Anda mengambilnya. Namun, Anda dapat menambahkannya kapan saja, dan Anda bahkan dapat menambahkannya tanpa mengubah kelas dasar dengan menggunakan semacam pembungkus.
sumber
Ya, tidak (atau terlalu jarang) menggunakan antarmuka mungkin merupakan hal yang buruk. Antarmuka (dalam arti abstrak, dan konstruksi bahasa C # / Java adalah pendekatan yang cukup baik dari pengertian abstrak itu) mendefinisikan titik interaksi eksplisit antara sistem dan subsistem. Ini membantu mengurangi kopling dan membuat sistem lebih mudah dikelola. Seperti halnya apa pun yang meningkatkan rawatan, menjadi semakin penting semakin besar suatu sistem.
sumber
Saya belum pernah menggunakan antarmuka selama bertahun-tahun. Tentu saja ini karena saya telah memprogram hampir secara eksklusif di Erlang sekarang selama bertahun-tahun dan seluruh konsep antarmuka tidak ada. (Yang paling dekat Anda dapatkan adalah "perilaku" dan itu tidak benar-benar hal yang sama kecuali jika Anda menyipit sangat keras dan melihat mereka dari sudut mata Anda.)
Jadi, sungguh, pertanyaan Anda bergantung pada paradigma (OOP dalam kasus ini) dan, lebih jauh, sangat tergantung pada bahasa (ada bahasa OOP tanpa antarmuka).
sumber
Jika Anda berbicara tentang menggunakan Java, salah satu alasan untuk menggunakan antarmuka adalah bahwa mereka memungkinkan penggunaan objek proxy tanpa pustaka pembuatan kode. Ini bisa menjadi keuntungan besar ketika Anda bekerja dengan kerangka kerja yang kompleks seperti Spring. Selain itu, beberapa fungsionalitas memerlukan antarmuka: RMI adalah contoh klasik dari ini, karena Anda harus menggambarkan fungsionalitas yang Anda sediakan dalam hal antarmuka (yang diturunkan dari
java.rmi.Remote
) namun Anda harus mengimplementasikannya.sumber
Hal-hal berubah ( MS Moles ), tetapi alasan utama yang menurut saya baik untuk kode hampir secara eksklusif untuk antarmuka adalah bahwa mereka mudah untuk diejek dan masuk secara alami ke dalam arsitektur IoC.
IMO Anda hanya boleh bekerja dengan antarmuka, atau DAO sepenuhnya bodoh jika memungkinkan. Setelah Anda masuk ke dalam pola pikir ini, dan Anda mulai menggunakan perpustakaan yang tidak mengekspos dirinya melalui antarmuka dan melakukan semuanya melalui objek konkret saya harus jujur, semuanya terasa agak kikuk.
sumber
Untuk proyek mode lama, orang menggunakan antarmuka untuk menghindari referensi melingkar, karena referensi melingkar bisa menjadi masalah pemeliharaan besar dalam jangka panjang.
Buruk:
Tidak buruk:
Biasanya A, B, PartOfClassB_AccessedByA diimplementasikan dengan file terpisah.
sumber
Pemrograman berbasis antarmuka membantu membuat kode lebih fleksibel dan lebih mudah untuk diuji. Kelas implementasi dapat diubah tanpa menyentuh kode klien [Fleksibilitas]. Sementara pengujian kode satu dapat menggantikan pemrograman berbasis oInterface yang sebenarnya membantu membuat kode lebih fleksibel dan lebih mudah untuk diuji. Kelas implementasi dapat diubah tanpa menyentuh kode klien [Fleksibilitas]. Sementara pengujian satu kode dapat mengganti objek aktual dengan benda tiruan [Testability] .bject dengan benda tiruan [Testability].
sumber