Saya tahu orang-orang membuat masalah besar menggunakan pengecualian untuk kontrol aliran tapi itu bukan masalah terbesar di sini. Saya melihat pelanggaran pemisahan permintaan perintah besar . Tetapi itu pun bukan yang terburuk.
Tidak, yang terburuk ada di sini:
/**
* Closes the door if open
*/
Kenapa segalanya meledak jika asumsi Anda tentang keadaan pintu salah tetapi lock()
hanya memperbaikinya untuk Anda? Lupa bahwa ini membuat tidak mungkin untuk mengunci pintu terbuka, yang sangat mungkin dan sesekali berguna. Tidak masalah di sini adalah Anda telah mencampur dua filosofi yang berbeda untuk berurusan dengan asumsi yang salah. Itu membingungkan. Jangan lakukan itu. Tidak pada tingkat abstraksi yang sama dengan gaya penamaan yang sama. Ow! Bawa salah satu ide itu ke luar. Metode layanan pintu semua harus bekerja dengan cara yang sama.
Adapun pelanggaran Pemisahan Permintaan Perintah saya tidak harus mencoba untuk menutup pintu untuk mencari tahu apakah itu ditutup atau terbuka. Aku seharusnya bisa bertanya. Layanan pintu tidak menyediakan cara untuk melakukan itu tanpa mungkin mengubah keadaan pintu. Itu membuat ini jauh lebih buruk daripada perintah yang juga terjadi untuk mengembalikan nilai (kesalahpahaman umum tentang apa CQS tentang). Di sini, perintah perubahan negara adalah satu-satunya cara untuk melakukan kueri! Ow!
Adapun pengecualian lebih mahal daripada kode status, itu pembicaraan optimasi. Cukup cepat cukup cepat. Tidak masalah sebenarnya adalah bahwa manusia tidak mengharapkan pengecualian untuk kasus tipikal. Anda dapat berdebat tentang apa yang paling Anda sukai. Bagi saya pertanyaan besarnya adalah seberapa mudah Anda membuat kode menggunakan.
ensureClosed(DoorService service, Door door){
// Need door closed and unlocked. No idea of its state. What to do?
try {
service.open(door)
service.close(door)
}
catch( DoorLockedException e ){
//Have no way to unlock the door so give up and die
log(e);
throw new NoOneGaveMeAKeyException(e);
}
catch( DoorAlreadyOpenedException e ){
try {
service.close(door);
}
catch( DoorAlreadyClosedException e ){
//Some multithreaded goof has been messing with our door.
//Oh well, this is what we wanted anyway.
//Hope they didn't lock it.
}
}
}
Tolong jangan buat saya menulis kode seperti ini. Tolong beri kami isLocked()
dan isClosed()
metode. Dengan itu saya bisa menulis sendiri ensureClosed()
dan ensureUnlocked()
metode yang mudah dibaca. Yang hanya membuang jika kondisi pos mereka dilanggar. Saya lebih suka menemukan Anda sudah menulis dan mengujinya tentu saja. Hanya saja, jangan mencampurnya dengan yang melempar ketika mereka tidak dapat mengubah negara. Paling tidak beri mereka nama yang berbeda.
Apa pun yang Anda lakukan, tolong jangan panggil apa pun tryClose()
. Itu nama yang mengerikan.
Adapun DoorLockedException
sendirian vs juga DoorAlreadyLockedException
sakit mengatakan ini: ini semua tentang menggunakan kode. Tolong jangan merancang layanan seperti ini tanpa menulis kode menggunakan dan melihat kekacauan yang Anda buat. Refactor dan mendesain ulang sampai menggunakan kode setidaknya dapat dibaca. Bahkan, pertimbangkan untuk menulis menggunakan kode terlebih dahulu.
ensureClosed(DoorService service, Door door){
if( !service.isClosed(door) ){
try{
service.close(door);
}
catch( DoorAlreadyClosedException e ){
//Some multithreaded goof has been messing with our door.
//Oh well, this is what we wanted anyway.
//Hope they didn't lock it.
}
} else {
//This is what you wanted, so quietly do nothing.
//Why are you even here? Who bothers to write empty else conditions?
}
}
ensureUnlocked(DoorService service, Door door){
if( service.islocked(door) ){
throw new NoOneGaveMeAKeyException();
}
}