Saya memiliki seorang kolega yang duduk di sebelah saya yang mendesain antarmuka seperti ini:
public interface IEventGetter {
public List<FooType> getFooList(String fooName, Date start, Date end)
throws Exception;
....
}
Masalahnya adalah, saat ini, kita tidak menggunakan parameter "end" ini di mana pun dalam kode kita, itu hanya ada karena kita mungkin harus menggunakannya beberapa waktu di masa depan.
Kami mencoba meyakinkannya bahwa ide buruk untuk menempatkan parameter ke antarmuka yang tidak digunakan saat ini, tetapi dia terus bersikeras bahwa banyak pekerjaan yang harus dilakukan jika kita menerapkan penggunaan tanggal "akhir" beberapa saat. nanti dan harus mengadaptasi semua kode itu.
Sekarang, pertanyaan saya adalah, apakah ada sumber yang menangani topik seperti ini dari guru pengkodean "terhormat" yang bisa kita tautkan dengannya?
end
parameter ke objek itu dan bahkan secara default agar tidak merusak kodenull
,. Menerapkan kelas kemudian dapat menimpa sesuai kebutuhan.IQueryable
(hanya dapat mengambil ekspresi tertentu) ke kode di luar DALJawaban:
Undang dia untuk belajar tentang YAGNI . Bagian Dasar Pemikiran dari halaman Wikipedia mungkin sangat menarik di sini:
Argumen lain yang mungkin:
“80% dari biaya seumur hidup sebuah perangkat lunak digunakan untuk pemeliharaan” . Menulis kode tepat pada waktunya mengurangi biaya perawatan: seseorang harus mempertahankan lebih sedikit kode, dan dapat fokus pada kode yang sebenarnya dibutuhkan.
Kode sumber ditulis sekali, tetapi dibaca puluhan kali. Argumen tambahan, tidak digunakan di mana pun, akan menyebabkan waktu terbuang untuk memahami mengapa ada argumen yang tidak diperlukan. Mengingat bahwa ini adalah antarmuka dengan beberapa kemungkinan implementasi membuat semuanya menjadi lebih sulit.
Kode sumber diharapkan untuk mendokumentasikan diri sendiri. Tanda tangan yang sebenarnya menyesatkan, karena pembaca akan berpikir bahwa itu
end
mempengaruhi hasil atau pelaksanaan metode.Orang yang menulis implementasi konkret dari antarmuka ini mungkin tidak mengerti bahwa argumen terakhir tidak boleh digunakan, yang akan mengarah pada pendekatan yang berbeda:
Saya tidak perlu
end
, jadi saya akan mengabaikan nilainya,Saya tidak perlu
end
, jadi saya akan melemparkan pengecualian jika tidaknull
,Saya tidak perlu
end
, tetapi entah bagaimana akan mencoba menggunakannya,Saya akan menulis banyak kode yang dapat digunakan nanti ketika
end
akan dibutuhkan.Namun ketahuilah bahwa kolega Anda mungkin benar.
Semua poin sebelumnya didasarkan pada fakta bahwa refactoring itu mudah, jadi menambahkan argumen nanti tidak akan membutuhkan banyak usaha. Tetapi ini adalah antarmuka, dan sebagai antarmuka, ini dapat digunakan oleh beberapa tim yang berkontribusi pada bagian lain dari produk Anda. Ini berarti bahwa mengubah antarmuka bisa sangat menyakitkan, dalam hal ini, YAGNI tidak benar-benar berlaku di sini.
Jawaban oleh hjk memberikan solusi yang baik: menambahkan metode ke antarmuka yang sudah digunakan tidak terlalu sulit, tetapi dalam beberapa kasus, ia memiliki biaya yang besar juga:
Beberapa kerangka kerja tidak mendukung kelebihan beban. Sebagai contoh dan jika saya ingat dengan baik (koreksi saya jika saya salah), .NET WCF tidak mendukung kelebihan beban.
Jika antarmuka memiliki banyak implementasi konkret, menambahkan metode ke antarmuka akan memerlukan melalui semua implementasi dan menambahkan metode di sana juga.
sumber
(lain kali)
Itu yang Anda butuhkan, kelebihan metode. Metode tambahan di masa depan dapat diperkenalkan secara transparan tanpa memengaruhi panggilan ke metode yang ada.
sumber
end
parameter tidak perlu sekarang dan telah menggunakanend
metode -less di seluruh proyek, maka memperbarui antarmuka adalah yang paling tidak dikhawatirkan karena menjadi keharusan untuk memperbarui kelas implementasi. Jawaban saya menargetkan secara khusus tentang bagian "sesuaikan semua kode", karena sepertinya rekan kerja berpikir sepanjang garis harus memperbarui penelepon metode asli di seluruh proyek untuk memperkenalkan parameter default / dummy ketiga .Seruan kepada otoritas tidak terlalu meyakinkan; lebih baik menyajikan argumen yang valid tidak peduli siapa yang mengatakannya.
Berikut ini adalah reductio ad absurdum yang harus meyakinkan atau menunjukkan bahwa rekan kerja Anda terjebak pada "benar" terlepas dari sensibilitas:
Yang benar-benar Anda butuhkan adalah
Anda tidak pernah tahu kapan Anda harus melakukan internasionalisasi untuk Klingon, jadi lebih baik Anda menjaganya sekarang karena akan membutuhkan banyak pekerjaan untuk retrofit dan Klingon tidak dikenal karena kesabaran mereka.
sumber
You never know when you'll have to internationalize for Klingon
. Itu sebabnya Anda harus melewati aCalendar
, dan biarkan kode klien memutuskan apakah dia ingin mengirimGregorianCalendar
atauKlingonCalendar
(saya yakin beberapa sudah melakukannya). Duh. :-pStarDate sdStart
danStarDate sdEnd
?Date
!HebrewDate start
danHebrewDate end
.Dari perspektif rekayasa perangkat lunak, saya percaya solusi yang tepat untuk masalah seperti ini adalah dalam pola pembangun. Ini jelas merupakan tautan dari penulis 'guru' untuk kolega Anda http://en.wikipedia.org/wiki/Builder_pattern .
Dalam pola pembangun, pengguna membuat objek yang berisi parameter. Wadah parameter ini kemudian akan diteruskan ke metode. Ini akan menangani setiap ekstensi dan kelebihan parameter yang dibutuhkan rekan Anda di masa depan sambil membuat semuanya menjadi sangat stabil saat perubahan harus dilakukan.
Contoh Anda akan menjadi:
sumber
IEventGetter
keISearchFootRequest
. Saya malah menyarankan sesuatu sepertipublic IFooFilter
dengan anggotapublic bool include(FooType item)
yang mengembalikan apakah akan memasukkan item atau tidak. Kemudian implementasi antarmuka individu dapat memutuskan bagaimana mereka akan melakukan penyaringan ituAnda tidak membutuhkannya sekarang, jadi jangan menambahkannya. Jika Anda membutuhkannya nanti, perluas antarmuka:
sumber
Tidak ada prinsip desain yang mutlak, jadi sementara saya sebagian besar setuju dengan jawaban lain, saya pikir saya akan berperan sebagai advokat setan dan mendiskusikan beberapa kondisi di mana saya akan mempertimbangkan untuk menerima solusi rekan Anda:
Now()
, kemudian menambahkan parameter menghapus efek samping, yang memiliki manfaat untuk caching dan pengujian unit. Mungkin memungkinkan untuk implementasi yang lebih sederhana. Atau mungkin lebih konsisten dengan API lain dalam kode Anda.Yang sedang berkata, dalam pengalaman saya konsekuensi wajar terbesar bagi YAGNI adalah YDKWFYN: Anda Tidak Tahu Bentuk Apa yang Anda Butuhkan (ya, saya baru saja membuat akronim itu). Bahkan jika memerlukan beberapa parameter batas mungkin relatif dapat diprediksi, itu mungkin mengambil bentuk batas halaman, atau jumlah hari, atau boolean yang menentukan untuk menggunakan tanggal akhir dari tabel preferensi pengguna, atau sejumlah hal lainnya.
Karena Anda belum memiliki persyaratan, Anda tidak dapat mengetahui jenis parameter yang seharusnya. Anda sering berakhir dengan antarmuka yang canggung yang tidak sesuai dengan kebutuhan Anda, atau harus mengubahnya.
sumber
Tidak ada informasi yang cukup untuk menjawab pertanyaan ini. Itu tergantung pada apa yang
getFooList
sebenarnya dilakukan, dan bagaimana melakukannya.Berikut adalah contoh nyata dari metode yang harus mendukung parameter tambahan, digunakan atau tidak.
Menerapkan metode yang beroperasi pada koleksi di mana Anda dapat menentukan awal tetapi tidak akhir koleksi sering konyol.
Anda benar-benar harus melihat masalah itu sendiri dan bertanya apakah parameter tidak masuk akal dalam konteks seluruh antarmuka, dan benar-benar berapa banyak beban yang dikenakan oleh parameter tambahan.
sumber
Saya khawatir kolega Anda mungkin sebenarnya memiliki poin yang sangat valid. Meskipun solusinya sebenarnya bukan yang terbaik.
Dari antarmuka yang diusulkan jelas bahwa
mengembalikan instance yang ditemukan dalam interval waktu tertentu. Jika klien saat ini tidak menggunakan parameter akhir, itu tidak mengubah fakta bahwa mereka mengharapkan instance ditemukan dalam interval waktu. Ini hanya berarti bahwa saat ini semua klien menggunakan interval terbuka (dari awal hingga selamanya)
Jadi antarmuka yang lebih baik adalah:
Jika Anda memberikan interval dengan metode pabrik statis:
maka klien bahkan tidak akan merasa perlu menentukan waktu akhir.
Pada saat yang sama antarmuka Anda lebih tepat menyampaikan apa yang dilakukannya, karena
getFooList(String, Date)
tidak berkomunikasi bahwa ini berkaitan dengan interval.Perhatikan bahwa saran saya mengikuti dari apa yang dilakukan metode saat ini, bukan dari apa yang seharusnya atau mungkin dilakukan di masa depan, dan dengan demikian prinsip YAGNI (yang memang sangat valid) tidak berlaku di sini.
sumber
Menambahkan parameter yang tidak digunakan membingungkan. Orang mungkin memanggil metode itu dengan asumsi fitur ini akan berfungsi.
Saya tidak akan menambahkannya. Sangat mudah untuk kemudian menambahkannya menggunakan refactoring dan secara mekanis memperbaiki situs panggilan. Dalam bahasa yang diketik secara statis, ini mudah dilakukan. Tidak perlu menambahkannya dengan penuh semangat.
Jika ada adalah alasan untuk memiliki parameter Anda dapat mencegah kebingungan: Tambahkan menegaskan dalam pelaksanaan antarmuka yang untuk menegakkan bahwa parameter ini dilalui sebagai nilai default. Jika seseorang secara tidak sengaja menggunakan parameter itu setidaknya dia akan segera melihat selama pengujian bahwa fitur ini tidak diterapkan. Ini menghilangkan risiko tergelincirnya bug ke dalam produksi.
sumber