Bu, kaynakların denenmesi yaklaşımlarında bile bu uyarıların neden olabileceğine dair daha kavramsal bir cevap olacaktır. Aynı zamanda maalesef, elde etmeyi umduğunuz kolay bir çözüm değildir.
Hata Kurtarma Başarısız Olamıyor
finally
Bir işlemin başarılı veya başarısız olmasına bakılmaksızın yürütülen işlem sonrası kontrol akışını modeller.
Başarısızlık durumunda, bir hatanın giderilmesinin ortasında , tamamen kurtarılmadan önce (hedefimize ulaşmadan önce ) finally
yürütülen mantığı yakalar .catch
Bir hatanın giderilmesinin ortasında bir hatayla karşılaşmak için sunduğu kavramsal sorunu düşünün .
Bir işlem yapmaya çalıştığımız bir veritabanı sunucusunu hayal edin ve yarı yolda başarısız olur (sunucunun hafızasının ortasında kaldığını söyleyin). Artık sunucu, hiçbir şey olmamış gibi işlemi geri almak istiyor. Yine de geri dönme sürecinde başka bir hatayla karşılaştığını hayal edin. Şimdi veritabanına yarı-bağlı bir işlem yaptık - işlemin atomitesi ve bölünmez doğası bozuldu ve veritabanının bütünlüğü artık tehlikeye girecek.
Bu kavramsal sorun, manuel hata kodu yayılımı ile C veya istisnalar ve yıkıcılar ile C ++ veya istisnalar dışında Java ile ilgili hatalarla ilgilenen herhangi bir dilde mevcuttur finally
.
finally
aynı şekilde sağlayan dillerde başarısız olamaz, yıkıcılar istisnalarla karşılaşma sürecinde C ++ 'da başarısız olamazlar.
Bu kavramsal ve zor problemden kaçınmanın tek yolu, işlemleri geri alma ve kaynakları ortada bırakma sürecinin muhtemelen özyinelemeli bir istisna / hata ile karşı karşıya kalmayacağından emin olmaktır.
Yani buradaki tek güvenli tasarım, writer.close()
başarısız olamayacak bir tasarım . Tasarımda, bu tür şeylerin iyileşme ortasında başarısız olabileceği senaryolardan kaçınmanın imkansız hale getirilmesi için genellikle yollar vardır.
Maalesef bu tek yol - hata kurtarma başarısız olamaz. Bunu sağlamanın en kolay yolu, bu tür "kaynakların serbest bırakılması" ve "ters yan etkiler" işlevlerinin başarısızlığa uğramaz hale getirmektir. Kolay değil - uygun hata kurtarma işlemi zor ve ne yazık ki test edilmesi de zor. Ancak bunu başarmanın yolu, "yok", "kapat", "kapat", "geri al" vb. İşlevlerin, işlem sırasında harici bir hatayla karşılaşmayacağından emin olmaktır; Mevcut bir hatadan kurtarma ortasında çağrılabilir.
Örnek: Günlüğe kaydetme
Diyelim ki bir finally
bloğun içine bir şeyler kaydetmek istiyorsunuz Bu, günlüğe kaydetme başarısız olmadıkça büyük bir sorun olacaktır . Günlük kaydı neredeyse kesin olarak başarısız olabilir, çünkü dosyaya daha fazla veri eklemek isteyebilir ve bu da başarısızlığın birçok nedenini kolayca bulabilir.
Dolayısıyla buradaki çözüm, finally
bloklarda kullanılan herhangi bir kayıt işlevinin arayan kişiye atamayacağı şekilde yapmaktır (başarısız olabilir, ancak atmaz). Bunu nasıl yapabiliriz? Diliniz nihayetinde yuvalanmış bir try / catch bloğu olması koşuluyla atmaya izin veriyorsa, bu, istisnaları yutarak ve onları hata kodlarına dönüştürerek arayana atmaktan kaçınmanın bir yolu olabilir; Ayrı olarak ve mevcut bir hata kurtarma yığınının dışında kalan bir süreç veya iş parçacığı gevşer. Bir hatayla karşılaşmanız mümkün olmadan bu işlemle iletişim kurabildiğiniz sürece, bu aynı zamanda istisnai güvenlik de olabilir, çünkü güvenlik konusu sadece aynı konu içinden tekrar tekrar atıyorsak bu senaryoda ortaya çıkar.
Bu durumda, giriş yapmamak ve hiçbir şey yapmamak dünyanın sonu olmadığından fırlatmamak kaydıyla kayıt başarısızlığından kurtulabiliriz (örneğin, herhangi bir kaynağı sızdırmaz veya yan etkileri geri almayı başaramaz).
Her neyse, bir yazılımı gerçekten de istisnai güvenli hale getirmenin ne kadar zor olduğunu hayal etmeye başlayacağınıza eminim. Görev açısından en kritik yazılımdan başka bir şeyle bunu en üst düzeye çıkarmak gerekli olmayabilir. Ancak, istisnai güvenliğin nasıl sağlanacağına dikkat çekmek önemlidir; çünkü çok genel amaçlı kütüphane yazarları burada sık sık karıştırabilir ve kütüphane kullanarak uygulamanızın istisna güvenliğini tamamen bozabilir.
SomeFileWriter
Eğer SomeFileWriter
içine atabilirseniz close
, o zaman, mevcut bir istisnadan kurtarmayı içeren bir bağlamda asla kapatmaya çalışmadığınız sürece, istisna işleme ile genellikle uyumsuz olduğunu söyleyebilirim. Eğer onun kodu sizin kontrolünüz dışındaysa, SOL olabiliriz ancak bu açık istisna güvenlik konusunun yazarlarına bildirimde bulunmaya değer. Eğer sizin kontrolünüz dahilindeyse, temel tavsiyem, gerekli olan herhangi bir şekilde kapatmanın mümkün olamayacağından emin olmak.
Bir işletim sisteminin bir dosyayı gerçekten kapatmayı başaramadığını hayal edin. Artık kapatıldığında bir dosyayı kapatmaya çalışan herhangi bir program kapatılamaz . Şimdi ne yapmamız gerekiyor, sadece uygulamayı açık ve açık tutmaya devam etmemiz (muhtemelen hayır), dosya kaynağını sızdırmanız ve sorunu görmezden gelmeniz (çok kritik değilse tamam olabilir)? En güvenli tasarım: bir dosyayı kapatmayı başaramamak imkansız.