Agar dapat dipertukarkan dan diuji, biasanya layanan dengan logika perlu memiliki antarmuka, mis
public class FooService: IFooService
{ ... }
Dari segi desain, saya setuju dengan ini, tetapi salah satu hal yang mengganggu saya dengan pendekatan ini adalah bahwa untuk satu layanan Anda perlu mendeklarasikan dua hal (kelas dan antarmuka), dan di tim kami, biasanya dua file (satu untuk kelas dan satu untuk antarmuka). Ketidaknyamanan lain adalah kesulitan dalam navigasi karena menggunakan "Pergi ke definisi" di IDE (VS2010) akan mengarah ke antarmuka (karena kelas lain merujuk ke antarmuka), bukan kelas yang sebenarnya.
Saya berpikir bahwa menulis IFooService dalam file yang sama dengan FooService akan mengurangi keanehan di atas. Lagipula, IFooService dan FooService sangat terkait. Apakah ini praktik yang baik? Apakah ada alasan bagus bahwa IFooService harus terletak di file-nya sendiri?
sumber
Jawaban:
Itu tidak harus di file sendiri, tetapi tim Anda harus memutuskan standar dan tetap menggunakannya.
Juga, Anda benar bahwa "Pergi ke definisi" akan membawa Anda ke antarmuka, tetapi jika Anda menginstal Resharper , hanya satu klik untuk membuka daftar kelas / antarmuka turunan dari antarmuka itu, jadi itu bukan masalah besar. Itu sebabnya saya menyimpan antarmuka dalam file terpisah.
sumber
Saya pikir Anda harus menyimpannya file terpisah. Seperti yang Anda katakan, idenya adalah untuk tetap dapat diuji dan dipertukarkan. Dengan menempatkan antarmuka dalam file yang sama dengan implementasi Anda, Anda mengasosiasikan antarmuka dengan implementasi spesifik. Jika Anda memutuskan untuk membuat objek tiruan atau implementasi lain, antarmuka tidak akan secara logis terpisah dari FooService.
sumber
Menurut SOLID, Anda tidak hanya harus membuat antarmuka, dan tidak hanya harus dalam file yang berbeda, tetapi juga harus dalam kumpulan yang berbeda.
Mengapa? Karena setiap perubahan pada file sumber yang dikompilasi menjadi sebuah perakitan membutuhkan kompilasi ulang dari perakitan tersebut, dan setiap perubahan pada suatu perakitan memerlukan kompilasi ulang dari setiap perakitan yang bergantung. Jadi, jika tujuan Anda, berdasarkan SOLID, adalah untuk dapat mengganti implementasi A dengan implementasi B, sedangkan kelas C bergantung pada antarmuka saya tidak harus mengetahui perbedaannya, Anda harus memastikan perakitan dengan I di dalamnya tidak berubah, sehingga melindungi penggunaan.
"Tapi itu hanya kompilasi ulang," aku mendengarmu protes. Mungkin memang begitu, tetapi di aplikasi ponsel cerdas Anda, yang lebih mudah pada bandwidth data pengguna Anda; mengunduh satu biner yang berubah, atau mengunduh biner itu dan lima lainnya dengan kode yang bergantung padanya? Tidak setiap program ditulis untuk dikonsumsi oleh komputer desktop pada LAN. Bahkan dalam kasus itu, di mana bandwidth dan memori murah, rilis patch yang lebih kecil dapat memiliki nilai karena mereka sepele untuk mendorong keluar ke seluruh LAN melalui Direktori Aktif atau lapisan manajemen domain serupa; pengguna Anda akan menunggu hanya beberapa detik untuk diterapkan pada waktu berikutnya mereka masuk, bukan beberapa menit untuk semuanya diinstal ulang. Belum lagi, semakin sedikit majelis yang harus dikompilasi ulang saat membangun proyek, semakin cepat akan dibangun,
Sekarang, penafian: Ini tidak selalu mungkin atau layak dilakukan. Cara termudah untuk melakukan ini adalah membuat proyek "antarmuka" terpusat. Ini memiliki kelemahan sendiri; kode menjadi kurang dapat digunakan kembali karena proyek antarmuka DAN proyek implementasi harus direferensikan di aplikasi lain menggunakan kembali lapisan ketekunan atau komponen kunci lainnya dari aplikasi Anda. Anda dapat mengatasi masalah itu dengan memisahkan antarmuka menjadi rakitan yang lebih erat, tetapi kemudian Anda memiliki lebih banyak proyek di aplikasi Anda yang membuat bangunan penuh sangat menyakitkan. Kuncinya adalah keseimbangan, dan mempertahankan desain yang digabungkan secara longgar; Anda biasanya dapat memindahkan file seperlunya, jadi ketika Anda melihat bahwa suatu kelas akan membutuhkan banyak perubahan, atau implementasi antarmuka yang baru diperlukan secara berkala (mungkin untuk berinteraksi dengan versi perangkat lunak lain yang baru saja didukung,
sumber
Mengapa memiliki file terpisah tidak nyaman? Bagi saya, ini jauh lebih rapi dan bersih. Adalah umum untuk membuat subfolder bernama "Antarmuka" dan menempelkan file IFooServer.cs Anda di sana, jika Anda ingin melihat lebih sedikit file di Solution Explorer Anda.
Alasan antarmuka didefinisikan dalam file sendiri adalah untuk alasan yang sama bahwa kelas biasanya didefinisikan dalam file mereka sendiri: manajemen proyek lebih sederhana ketika struktur logis dan struktur file Anda identik, sehingga Anda selalu tahu file mana kelas yang ditentukan didefinisikan in. Ini dapat membuat hidup Anda lebih mudah ketika debugging (pengecualian stack stack biasanya memberi Anda nomor file dan baris) atau ketika menggabungkan kode sumber dalam repositori kontrol sumber.
sumber
Sering kali merupakan praktik yang baik untuk membiarkan file kode Anda hanya berisi satu kelas, atau satu antarmuka tunggal. Tetapi praktik pengkodean ini merupakan sarana untuk mencapai tujuan - untuk menyusun struktur kode Anda dengan lebih baik sehingga memudahkan untuk dikerjakan. Jika Anda, dan tim Anda, merasa lebih mudah untuk bekerja dengan jika kelas disimpan bersama dengan antarmuka mereka, dengan segala cara melakukannya.
Secara pribadi saya lebih suka memiliki antarmuka dan kelas dalam file yang sama ketika hanya ada satu kelas yang mengimplementasikan antarmuka, seperti dalam kasus Anda.
Mengenai masalah yang Anda miliki dengan navigasi, saya bisa sangat merekomendasikan ReSharper . Ini berisi beberapa cara pintas yang sangat berguna untuk melompat langsung ke metode yang menerapkan metode antarmuka tertentu.
sumber
Ada banyak waktu di mana Anda ingin antarmuka Anda tidak hanya di file terpisah ke kelas, tetapi bahkan di majelis terpisah sama sekali.
Misalnya, antarmuka Kontrak Layanan WCF dapat dibagikan oleh klien dan layanan jika Anda memiliki kendali atas kedua ujung kabel. Dengan memindahkan antarmuka ke rakitannya sendiri, ia akan memiliki lebih sedikit ketergantungan rakitan sendiri. Ini membuatnya lebih mudah bagi klien untuk mengkonsumsi, melonggarkan kopling dengan implementasinya.
sumber
Jarang, jika pernah, masuk akal untuk memiliki implementasi tunggal dari antarmuka 1 . Jika Anda meletakkan antarmuka publik dan kelas publik yang mengimplementasikan antarmuka itu ke file yang sama, kemungkinan besar Anda tidak perlu antarmuka.
Ketika kelas yang Anda tempatkan bersama dengan antarmuka adalah abstrak , dan Anda tahu bahwa semua implementasi antarmuka Anda harus mewarisi kelas abstrak itu, menempatkan keduanya di file yang sama masuk akal. Anda harus tetap meneliti keputusan Anda untuk menggunakan antarmuka: tanyakan pada diri sendiri apakah kelas abstrak dengan sendirinya akan baik-baik saja, dan lepaskan antarmuka jika jawabannya setuju.
Namun, secara umum, Anda harus tetap berpegang pada strategi "satu kelas publik / antarmuka sesuai dengan satu file": strategi ini mudah diikuti, dan itu membuat pohon sumber Anda lebih mudah dinavigasi.
1 Satu pengecualian penting adalah ketika Anda perlu memiliki antarmuka untuk tujuan pengujian, karena pilihan kerangka kerja mengejek Anda menempatkan persyaratan tambahan ini pada kode Anda.
sumber
sealed
. Jika Anda mencurigai bahwa suatu saat nanti Anda mungkin menambahkan subkelas kedua, Anda langsung masuk ke antarmuka. PS Asisten refactoring berkualitas bagus dapat menjadi milik Anda dengan harga sederhana dari satu lisensi ReSharper :)virtual
.Antarmuka milik klien mereka bukan untuk implementasi mereka, sebagaimana didefinisikan dalam Prinsip Agile, Praktik dan Pola oleh Robert C. Martin. Jadi, menggabungkan antarmuka dan implementasi di tempat yang sama bertentangan dengan prinsipnya.
Kode klien tergantung pada antarmuka. Ini memungkinkan kemungkinan kompilasi dan penyebaran kode klien dan antarmuka tanpa implementasi. Daripada Anda dapat memiliki implementasi yang berbeda bekerja seperti plugin ke kode klien.
PEMBARUAN: Ini bukan prinsip yang hanya gesit di sini. Geng Empat dalam Pola Desain, kembali pada '94, sudah berbicara tentang klien yang mengikuti antarmuka dan pemrograman ke antarmuka. Pandangan mereka serupa.
sumber
Saya pribadi tidak suka "Saya" di depan sebuah antarmuka. Sebagai pengguna tipe seperti itu saya tidak ingin melihat bahwa ini adalah antarmuka atau bukan. Jenisnya adalah hal yang menarik. Dalam hal dependensi, FooService Anda adalah SATU kemungkinan implementasi IFooService. Antarmuka harus dekat dengan tempat digunakannya. Di sisi lain implementasi harus di tempat di mana ia dapat dengan mudah diubah tanpa mempengaruhi klien. Jadi, saya lebih suka dua file - biasanya.
sumber
new
, tetapi di sisi lain, saya dapat menggunakannya bersama atau berlawanan. DanI
ini adalah konvensi penamaan yang mapan di .Net, jadi itu adalah alasan yang bagus untuk mematuhinya, jika hanya untuk konsistensi dengan jenis lainnya.I
antarmuka hanya pengantar argumen saya tentang pemisahan dalam dua file. Kode lebih mudah dibaca dan itu membuat inversi dari dependensi lebih jelas.I
normal di lingkungan Anda: Gunakan! (Tapi saya tidak suka :))Pengkodean ke antarmuka bisa buruk, sebenarnya diperlakukan sebagai anti-pola untuk konteks tertentu, dan bukan hukum. Biasanya contoh pengkodean untuk antarmuka anti-pola yang baik adalah ketika Anda memiliki antarmuka yang hanya memiliki satu implementasi dalam aplikasi Anda. Lain akan jika file antarmuka menjadi begitu merepotkan bahwa Anda harus menyembunyikan deklarasi di file kelas yang diimplementasikan.
sumber
Menempatkan kelas dan antarmuka ke file yang sama tidak membatasi penggunaan keduanya. Antarmuka masih dapat digunakan untuk mengolok-olok dll dengan cara yang sama, bahkan jika itu dalam file yang sama dengan kelas yang mengimplementasikannya. Pertanyaan itu dapat dianggap murni sebagai salah satu kenyamanan organisasi, dalam hal ini saya akan mengatakan melakukan apa pun yang membuat hidup Anda lebih mudah!
Tentu saja, orang dapat berargumentasi bahwa memiliki keduanya dalam file yang sama dapat menyebabkan mereka yang tidak waspada menganggap mereka lebih diprogram daripada mereka yang sebenarnya, yang merupakan risiko.
Secara pribadi, jika saya menemukan basis kode yang menggunakan satu konvensi lebih dari yang lain, saya tidak akan terlalu peduli.
sumber