Saya pernah mendengar bahwa disarankan untuk memvalidasi argumen metode publik:
- Haruskah seseorang memeriksa nol jika dia tidak mengharapkan nol?
- Haruskah metode memvalidasi parameternya?
- MSDN - CA1062: Validasi argumen metode publik (Saya memiliki latar belakang .NET tetapi pertanyaannya tidak spesifik C #)
Motivasi bisa dimengerti. Jika modul akan digunakan dengan cara yang salah, kami ingin membuang pengecualian segera alih-alih perilaku yang tidak terduga.
Yang menggangguku, adalah bahwa argumen yang salah bukanlah satu-satunya kesalahan yang dapat dibuat saat menggunakan modul. Inilah beberapa skenario kesalahan di mana kita perlu menambahkan logika pemeriksaan jika kita mengikuti rekomendasi dan tidak ingin eskalasi kesalahan:
- Panggilan masuk - argumen yang tidak terduga
- Panggilan masuk - modul dalam kondisi yang salah
- Panggilan eksternal - hasil yang tidak terduga dikembalikan
- Panggilan eksternal - efek samping yang tidak terduga (masuk dua kali ke modul panggilan, melanggar keadaan dependensi lainnya)
Saya sudah mencoba memperhitungkan semua kondisi ini dan menulis modul sederhana dengan satu metode (maaf, bukan-C # guys):
public sealed class Room
{
private readonly IDoorFactory _doorFactory;
private bool _entered;
private IDoor _door;
public Room(IDoorFactory doorFactory)
{
if (doorFactory == null)
throw new ArgumentNullException("doorFactory");
_doorFactory = doorFactory;
}
public void Open()
{
if (_door != null)
throw new InvalidOperationException("Room is already opened");
if (_entered)
throw new InvalidOperationException("Double entry is not allowed");
_entered = true;
_door = _doorFactory.Create();
if (_door == null)
throw new IncompatibleDependencyException("doorFactory");
_door.Open();
_entered = false;
}
}
Sekarang Aman =)
Cukup menyeramkan. Tapi bayangkan betapa menyeramkannya dalam modul nyata dengan lusinan metode, keadaan kompleks dan banyak panggilan eksternal (hai, pecinta injeksi ketergantungan!). Perhatikan bahwa jika Anda memanggil modul yang perilakunya dapat diganti (kelas tidak disegel dalam C #) maka Anda membuat panggilan eksternal dan konsekuensinya tidak dapat diprediksi pada ruang lingkup pemanggil.
Kesimpulannya, apa jalan yang benar dan mengapa? Jika Anda dapat memilih dari opsi di bawah ini, tolong jawab pertanyaan tambahan.
Periksa seluruh penggunaan modul. Apakah kita perlu tes unit? Apakah ada contoh kode seperti itu? Haruskah ketergantungan injeksi dibatasi dalam penggunaan (karena akan menyebabkan lebih banyak memeriksa logika)? Apakah tidak praktis untuk memindahkan cek ke waktu debug (tidak termasuk dalam rilis)?
Periksa hanya argumen. Dari pengalaman saya, pemeriksaan argumen - terutama pemeriksaan nol - adalah pemeriksaan yang paling tidak efektif, karena kesalahan argumen jarang mengarah pada kesalahan kompleks dan eskalasi kesalahan. Sebagian besar waktu Anda akan mendapatkan NullReferenceException
di baris berikutnya. Jadi mengapa cek argumen begitu istimewa?
Jangan periksa penggunaan modul. Pendapat ini sangat tidak populer, dapatkah Anda menjelaskan mengapa?