Mülklerin yan etkileri olmalı


19

C # 'daki özelliklerin durumlarındaki bir değişikliğin bildirilmesinin yanı sıra yan etkileri olmalı mı?

Birkaç farklı şekilde kullanılan özellikler gördüm. Değeri ilk kez erişecek olan özelliklerden, farklı bir sayfaya yönlendirmeye neden olmak gibi büyük yan etkileri olan özelliklere.



1
@ Job'ın bulguları arasında, Neden C # 'da Özellikler kullanmaktan kaçınmalıyım? aka Jeffrey Richter'in görüşü bu soru ile çok ilgili.
rwong

@rwong İlgili evet ama tamamen anlamsız - yine de okunmalıdır (vurguladığı sorunların farkında olmak için). En azından bu konuda Skeet kampındayım.
Apoorv Khurasia

Her ne kadar bu inşaatçılar ile ilgili olsa da, bu aynı zamanda önemlidir: programmers.stackexchange.com/a/164255/1996
Jim G.

Yanıtlar:


40

Bir özellik ayarlayıcı hemen hemen her durumda yan etkilere sahip olacağından , salt okunur özellikler veya en azından özellik alıcıları hakkında konuştuğunuzu varsayıyorum . Aksi takdirde çok kullanışlı değil.

Genel olarak, iyi bir tasarım en az sürpriz ilkesini takip eder . Arayanların sizden beklemediği şeyleri yapmayın, özellikle bu şeyler gelecekteki sonuçları değiştirebilirse .

Genel olarak , mülk sahiplerinin yan etkileri olmamalıdır.

Ancak , "yan etki" ile neyi kastettiğimize dikkat edelim .

Bir yan etki , teknik olarak herhangi bir durum değişikliğidir. Bu kamuya açık bir devlet olabilir ya da ... tamamen özel bir devlet olabilir.

Tembel / ertelenmiş yükleyiciler, neredeyse tamamen özel olan bir durum örneğidir. Sürece o zaman gerçekten, yani kaynak boşaltmak için arayanın sorumluluğu olmasın da azaltarak ertelenmiş başlatma kullanarak genel olarak sürpriz ve karmaşıklığını. Arayan kişi normal olarak bir yapının başlatılmasını açıkça belirtmek zorunda değildir . Yani, tembel başlatma yok değil yukarıdaki ilkeyi ihlal ediyor.

Başka bir örnek, senkronize edilmiş bir özelliktir. Bir yöntemin iş parçacığı açısından güvenli olması için, genellikle kritik bölüm veya muteks tarafından korunması gerekir. Önemli bir bölümü girme veya muteksi elde olan bir yan etkisi; durumu değiştiriyorsunuz, genellikle küresel durumu. Bununla birlikte, bu yan etki, çok daha kötü bir sürprizi - başka bir iş parçacığı tarafından değiştirilen (veya daha kötü, kısmen değiştirilen) sürprizi önlemek için gereklidir .

Bu yüzden kısıtlamayı biraz aşağıdaki gibi gevşetirim: Özellik okumalarının semantiklerini değiştiren görünür yan etkileri veya yan etkileri olmamalıdır .

Arayan kişinin herhangi bir yan etkiden etkilenmesinin veya hatta yan etkinin farkında olmasının olası bir yolu yoksa, bu yan etki herhangi bir zarar vermez. Belirli bir yan etkinin varlığını doğrulamak için bir test yazmanız imkansızsa, özel bir uygulama detayı olarak etiketlenecek kadar yerelleştirilmiştir ve bu nedenle dış dünya için meşru bir endişe yoktur.

Ancak dikkatli olun; Pratik bir kural olarak, sen gerektiğini sıklıkla özel uygulama detay beklenmedik sızıntı ve kamu olabilir olmak ne düşünürseniz düşünün, çünkü yan etkilerinden kaçınmak için deneyin.


2
+1 - "ne zaman" dışında bir "
irade

Alıcıda kabul edilebilir bir yan etkiye başka bir örnek: Bir kayıt işlevi.
Loren Pechtel

5

Sorunuzu bir soru ile cevaplayacağım: Bir formun Width özelliğini değiştirdiğinizde ne olur?

Sadece kafamın üstünde, bu:

  • Destek alanının değerini değiştirin.
  • Bir olayı başlat.
  • Formun boyutlarını değiştirin, değişikliği pencere yöneticisine bildirin ve yeniden boyama isteyin.
  • Form yeniden boyutlandırıldığında boyutu veya konumu değiştirmesi gereken herhangi birinin yapabilmesi için değişiklikleri değişiklik biçiminde bilgilendirin.
  • Çünkü olayları değiştiren tüm kontroller ve pencere yöneticisine yeniden çizilmeleri gerektiğini söyleyin.
  • Muhtemelen başka şeyler de.

(Feragatname: Ben bir .NET geliştiricisi değil, bir Delphi geliştiricisiyim. Bu C # için% 100 doğru olmayabilir, ancak özellikle orijinal .NET çerçevesinin ne kadarının Delphi'ye dayandığını göz önünde bulundurarak oldukça yakın olduğuna eminim.)

Tüm bu "yan etkiler" formdaki Width özelliğini değiştirdiğinizde olur. Bunlardan herhangi biri bir şekilde uygunsuz veya yanlış görünüyor mu?


kendini çağıran sonsuz bir döngüye girmediği sürece. Bundan kaçınmak için, her "değişiklik" en az üç olaya eşlenir: biri değişiklikten önce, biri değişiklik sırasında tetiklenir ve diğeri bittikten sonra tetiklenir.
rwong

5

Microsoft Tasarım Kurallarına , özellikle de bunlardan birine göz atın :

CA1024: Uygun durumlarda özellikleri kullanın

... Bir yöntem, bu koşullardan biri varsa mülk haline gelmek için iyi bir adaydır:

  • Hiçbir argüman almaz ve bir nesnenin durum bilgisini döndürür.
  • Bir nesnenin durumunun bir kısmını ayarlamak için tek bir argümanı kabul eder.

Özellikler sanki alanmış gibi davranmalıdır; yöntem kullanılamazsa, bir özellik olarak değiştirilmemelidir. Aşağıdaki durumlarda yöntemler özelliklerden daha iyidir:

  • Yöntem zaman alıcı bir işlem gerçekleştirir. Yöntem, bir alanın değerini ayarlamak veya almak için gereken süreden algılanabilir derecede yavaştır.
  • Yöntem bir dönüşüm gerçekleştirir. Bir alana erişmek, depoladığı verilerin dönüştürülmüş bir sürümünü döndürmez.
  • Get yönteminin gözlenebilir bir yan etkisi vardır. Bir alanın değerini almak herhangi bir yan etki yaratmaz.
  • Yürütme sırası önemlidir. Bir alanın değerinin ayarlanması, diğer işlemlerin gerçekleşmesine bağlı değildir.
  • Yöntemin art arda iki kez çağrılması farklı sonuçlar yaratır.
  • Yöntem statiktir ancak arayan tarafından değiştirilebilen bir nesne döndürür. Bir alanın değerini almak, çağıranın alan tarafından saklanan verileri değiştirmesine izin vermez.
  • Yöntem bir dizi döndürür ...

2

Mülklerin yan etkileri olmaması gerektiğine inanıyorum. Ancak bu kuralın bir istisnası vardır: tembel yükleme. Bir mülke tembel bir şey yüklemek istiyorsanız, sorun değil, çünkü istemci tembel yüklemenin gittiğini söyleyemez ve genellikle umursamaz.

EDIT : Oh, bir şey daha - "PropertyXYZ Değişti!" (örn. INotifyPropertyChanged) - ayarlayıcılarda sorun yok.


2

Daha önce bahsedilen tembel yüklemeye ek olarak, günlük tutma işlevleri de vardır. Bunlar nadirdir ancak söz konusu değildir.


2

Programlamada neredeyse hiç mutlaklık yoktur, sorunuzu cevaplamak için nesnelerin bazı istenen özelliklerine bakmamız ve bunun bizim durumumuz için geçerli bir şey olup olmadığını görmemiz gerekir.

  1. Sınıfların kolayca test edilebilir olmasını istiyoruz.
  2. Sınıfların eşzamanlılığı desteklemesini istiyoruz
  3. Üçüncü taraflar için sınıfların akla kolay gelmesini istiyoruz

Bu soruların bazılarına evet cevabı verirsek, muhtemelen mülkler ve yan etkileri hakkında çok dikkatli düşünmek iyi bir fikirdir. Yan etkileri söylediğinizde , değeri güncellemenin kendi başına bir yan etki olduğu için ikincil yan etkiler anlamına geldiğini varsayıyorum .

Genel olarak ne kadar çok yan etki olursa bir sınıfın testi o kadar zor olacaktır. İkincil yan etkiler ne kadar fazla olursa, eşzamanlılığın üstesinden gelmek o kadar zor olacaktır, ancak bu yine de bazı büyük tasarım düşüncelerini gerektiren zor bir konudur.

Büyük sorun, muhtemelen sınıfınızı "kara kutu" olarak gören insanlar içindir, bazı devletlerin sadece bir mülkü okudukları için değiştiği veya başka bir mülkün değiştiği için başka bir mülkün değiştiği ( basamaklı güncellemelere).

Yani genel olarak hayır, özelliklerin mantıklı ve kolay olabildiğince basit olmasını istiyoruz, bu tasarım kararında ima edilir, aksi takdirde bir yöntem olurdu. İyi bir programcı her zaman kuralları ihlal edebilir, sadece gerçekten iyi bir nedeniniz olduğundan emin olun :)

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.