İş kurallarını istisnalar ile temsil etmek


16

Pahalı olduğunu biliyorum ama (IMO) Çok iyi bir uygulama olduğuna inanıyorum. Söylemek gibi kurallardan bahsediyorum, eğer bir satış elemanı değilseniz bir Faturayı kaydedemezsiniz ... bu durumda 'yetkiniz yok' diyen bir istisna atmak ya da böyle ...

Başka bir yaklaşım, durumu veya benzeri bir şey olan nesneler olması olurdu

Başka bir yaklaşım var mı? onun hakkında nasıl hissediyorsun?

Yanıtlar:


15

İstisnalar dışında bireysel iş kuralı kontrollerini temsil etmek istiyorsanız, bunun çok iyi bir fikir olduğunu düşünmüyorum. Çoğu zaman, birden fazla başarısız durumu bildirmeniz ve ilkinde durmamanız gerekir.

Öte yandan, tüm kuralları kontrol etmenin ve ardından özetle bir istisna atmanın iyi bir uygulama olduğuna inanıyorum .


1
Uygulamalarımda tam olarak böyle idare ediyorum. Hayatımı kolaylaştırmak için FluentValidation'ı kullanmak ve ValidateAndThrow yöntemi günümü kurtarıyor.
Matteo Mosca

Bir UI uygulamasında tamamen katılıyorum, ancak hizmet katmanı uygulamasında, iş kurallarına uymayan bir nesneyi geçersem bir istisna oluştururdum. Eğer ikisini bir arada kullanıyorsanız, bazen matiasha'nın son cümlede açıklandığı gibi bir doğrulama işlevi veya karmaşık bir hata eklersiniz.
Bill

8
Etki alanına özgü bir istisna atın . Bu arasına ayrı sağlar bizim ve not-bizimki daha yüksek yukarı.

@ Thorbjørn Ravn Andersen +1 "alana özgü" harika bir ek
Justin Ohms

1
@JamesPoulson JamesPoulsonExceptionbir alt sınıf olarak oluşturmak RuntimeExceptionve sonra özgün istisnasını sağlamak için yeterli olabilir cause. Daha sonra if (exception instanceof JamesPoulsonException)... ayırt etmek için basitçe söyleyebilirsiniz . getCause()Orijinal istisnaya ulaşmak için yöntemi kullanın .

9

Bize verdiğiniz örnekte, bir istisna oluşturmanın kötü bir fikir olduğunu düşünüyorum. Kullanıcının çalışmaya başlamadan önce yetkilendirilmediğini biliyorsanız ve yine de bazı işlevlerini yerine getirmelerine izin veriyorsanız ve daha sonra görevi tamamladıktan SONRA bir mesajla şapırtılıyorsanız, bu sadece kötü bir tasarımdır.

İş kurallarını uygulamak için istisnaları kullanmak iyi bir tasarım değildir.


Söylediklerinizi anladığım şey, kullanıcı arayüzüne katılmamanız. Bununla iyiyim. Çok daha kullanıcı dostu bir kullanıcı arayüzünün izin verilmeyen bir şeyi güncellemeye çalışmanıza izin vermeyeceğini kabul ediyorum. Ancak bu, iş çekirdeğindeki doğrulama ve istisna kontrolünün gereksiz olduğu anlamına gelmez. Aksine, bir zorunluluk olduğuna inanıyorum. Kötü programlanmış bir kullanıcı arayüzünün BL yanlış kullanımına izin vermemesini sağlamak için onlara ihtiyacınız vardır.
Fede

8
@Fede: bu endişelerin ayrılması meselesi. Kullanıcı arayüzü, kullanıcının niyetlerini toplamaktan ve iş katmanından geri bildirimde bulunmaktan sorumludur. İş katmanının işi, kullanıcı arayüzü tarafından toplanan bilgileri analiz etmek, analiz etmek ve kullanıcı arayüzüne rapor vermek ve / veya veri katmanından bazı verileri devam ettirmesini istemektir. Bu katmanlar arasında sadece gevşek bağlantı olmalıdır. İstisnalar gevşek bağlamaya zayıf ve kötü bir yaklaşımdır. Yalnızca katmanlar arasında gerçek sınıfların paylaşılması anlamına gelmez, aynı zamanda beklenmedik arızaları ele almayı amaçlayan bir mekanizma da çağırır.
Adam Crossland

@Adam - İyi dedi ve tam olarak noktada.
Walter

1
@Adam - Endişe konularının ayrılmasıyla sizi takip etmeyin. Kullanıcı arayüzünde kimse bir CustomerNameInLowercaseException işlemek için beklemeyin (lütfen, ben de istisna bile var olmadığını umuyoruz!). Yalnızca genel bir ValidationException işleyebilir. Ayrıca, kullanıcı arayüzünün yalnızca bilgi toplaması ve tüm bu thig ile seninle birlikte% 100'üm. Daha önce söylediğim şey, kullanıcı arayüzünde ne yaparsanız yapın, BL'nin her girişin iyi olduğunu varsaymaması gerekir. Sadece savunma amaçlı bir programlama.
Fede

@Fede: Her girişin iyi olmasını sağlamak Business Layer'ın işidir. Kullanıcı arayüzü bunu yapıyorsa iş mantığı uyguluyor. Bir giriş alanı basamağı kısıtlı olduğuna dair bir durum olduğunu ve BL görürse Şimdi, alfa karakterler tarafından tüm yollarla atmak bir istisna . Bir bileşen başka bir bileşenden geçersiz girdiler aldığında , bir istisna atmak mantıklı ve doğrudur. Arayüz bozuldu ve sistem bozuldu. Ancak, girdileri doğrulamak iş mantığını yürütmekten çok farklıdır. Çok farklı iki şey.
Adam Crossland

5

İyi iş mantığı yaratmada bir İstisna atmanın ne kadar değerli olduğunu görmüyorum. İş mantığının ele alınmasında, bir sistemin işleyişinde beklenmedik koşullara yönelik bir sistemin kullanılmasını içermeyen düzinelerce yaklaşım vardır.

Edilir beklenen iş mantığında, şartların yerine olmayacağını; ilk etapta olmasının nedeni budur ve beklenmedik G / Ç arızalarını, bellek dışı hataları ve boş referansları işleyen aynı mekanizma üzerinde piggyback yapmak istemezsiniz. Bunlar sistemin hatalarıdır, ancak karşılanmayan iş koşullarını tespit etmek sistemin başarılı bir şekilde çalışmasıdır.

Ayrıca, istenmeyen sonuçlar için olgunlaşmış bir sistemdir. Bir istisna bir noktada yakalanması gerektiğinden, yeni bir iş kuralı istisnasının, amaçlanmadığı bir yerde yakalanmakla sonuçlanması veya gerçekte amaçlanmayan istisnaları yakalayan iş kurallarını arayan koda sahip olma riskiniz vardır. onun için. Evet, bu koşullar iyi kodlama uygulamalarıyla açıklanabilir, ancak birden fazla geliştiricinin üzerinde çalıştığı önemsiz herhangi bir sistemde hatalar olur ve bunların maliyetli hatalar olmayacağını ummanız gerekir.


1
Katılıyorum, istisnalar istisna olarak adlandırılıyor çünkü gerçekleşmeleri beklenmiyor. Öte yandan, hizmet kuralınızda bir istisna ile iş kurallarının uygulanması zorunlu değildir. Kullanılmasını beklemezsiniz, istemciden yalnızca işlemleri çağırmasını ve yalnızca geçerli koşulları karşılayan verileri göndermesini beklersiniz; ancak bir koruma katmanı oluşturmak istersiniz çünkü istemci kodlamasında hatalar olabileceğini biliyorsunuzdur. Veritabanında yabancı anahtar kısıtlamaları kullanmak gibi bir şey: İnsanların verileri doğru şekilde eklemelerini ve güncellemelerini beklersiniz, ancak bir programlama hatası nedeniyle başarısız olabileceklerini bilirsiniz.
Jeremy

2

iş kurallarını ifade etmek bir şeydir, bunları uygulamak başka bir şeydir

kullanıcı deneyimini düşünün; Kullanıcı bir satış elemanı değilse, neden onlara 'fatura oluşturmak' yazan bir düğme vermek hiç ?


1
Sadece bir düğme vermediğin için, sana zaten bir şey yapman için mesaj göndermeyecekleri anlamına gelmez. Güvenlik kurallarının ne kadar kolay olacağını düşünün ..
jmoreno

Kullanıcının X yapmasına izin verilmiyorsa, onlara "X Yap" yazan bir düğme vermeyin. En iyi güvenlik cehalettir - kullanıcıya yapamayacakları şeyleri söyleme;)
Steven A. Lowe

1

Bu tamamen ne yapıldığına bağlıdır.

İlk olarak, istediğiniz gerçek davranış nedir? Birisi kendi bilgilerini giriyorsa, reddetme ve aslında "Bunu yapamazsınız" yazan bir iletişim kutusu muhtemelen doğrudur. Bu bir veri giriş kişisiyse, bir yığın formdan çalışıyorsa, bir iletişim kutusu da muhtemelen iyidir ve veri giriş kişisi geçersiz formları özel bir yığına koyabilir. Toplu işlem yapıyorsanız, işleri durma noktasına getirmek istemezsiniz, ancak işaretler ve bir sonrakine geçer.

Davranışınız olduğunda, onu nasıl uygulayacağınıza karar vermeniz gerekir. İstisna getiren bir iş kuralları denetleyicisine sahip olmak muhtemelen iyi bir fikirdir. Bir dönüş kodu döndürmek ve iletmek yanlış gidebilecek başka bir şeydir ve hatalı girişlerin daha da ilerlemesini kesinlikle istemezsiniz.

Performans gideri konusunda endişelenmeyin. Bir kişinin veri girmesi durumunda, söz konusu diğer zamanlara kıyasla önemsizdir. Tipik olarak, insan bu sistemde en fazla zamanı alacaktır. Toplu iş durumunda, istisnalar bir performans sorunu ise, çok fazla kötü kayıt girersiniz ve gerçekte bunların tümünü işleme ve yeniden girme, istisnalardan daha fazla bir sorun olacaktır.


0

Tutarlı, sağlam ve iyi tasarlanmış bir istisna API'sine sahip olmak çok uygundur. İş kurallarını uygulamak için bunu kullanmak da uygun olabilir. Aslında tecrübelerime göre, iş kuralı ne kadar karmaşıksa, bu şekilde ele alınma olasılığı o kadar artar. İstisnaların beklendiği bir sistemi yazmak, yetkili dallanma mantığı yazmaktan daha kolay olmasa da, genellikle kolaydır.

Bu, tek bir cümle ile tarif edilebilecek basit kuralların genellikle hangisine bağlı olarak önleyici veya yetkili bir şekilde uygulanması gerektiğini ifade eder. Bununla birlikte, çok boyutlu olan ve üç veya dörtten fazla faktör gerektiren bir kuralınız varsa (özellikle bu faktörlerin seçimi diğer faktörlerden birine veya daha fazlasına dayandıysa), istisna kodlaması daha sürdürülebilir olabilir. Genellikle bu durumlarda mantık yolunun atılması gereken birçok öncü istisnası olacaktır (eylemin neden gerçekleştirilemediğini kontrol eder) veya (veya tersi) güvenliğe (eylemin yetkilendirildiğini kontrol etmek için) düşme olur ), bazen kontrol edilmesi gereken bazı yetkili birikim mantığı olacaktır (torun / ata kullanılabilirliği, nesnelerin konması gereken öncü durumlar vb.).

Bu tür istisna atma işlemlerinden kaynaklanan bir avantaj, öncül istisnaları projenizin birden çok alanında ayırmanıza ve yeniden kullanmanıza izin vermesidir. (Bu, Unsur Odaklı Programlamanın özüdür.) Bunu yaparak, genel iş kurallarınızın belirli bir yönünü müstakil ve sürdürülebilir bir bileşende kapsüllersiniz. Genel olarak bu bileşenler, atılan hata mesajlarıyla 1-1'e karşılık gelir. (Bazen birkaç farklı istisna getiren bir bileşene sahip olsanız da, neredeyse hiçbir zaman birden fazla bileşenden aynı istisnayı atmamalısınız.)

Kanımca, istisna tabanlı sistemler tasarlamak daha zordur ve tüm N seviyelerinde istisna sürecini oluşturmak zorunda olduğunuz için ilk geliştirme süresi daha uzundur. Ancak bu sistem genellikle daha kararlı hale gelir. 'Başarısız olmayacak' bir sistem tasarlamak asla mümkün olmasa da, istisna tabanlı tasarımın yararı her zaman başarısızlığı beklemenizdir. Çoğu insan için süreç karşı sezgisel olabilir. Yön sormak ve birisinin size tüm sokakları açmamanız gerektiğini söylemesini sağlamak gibi.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.