Bir sınıfın tek sorumluluk ilkesini karşılayıp karşılamadığı nasıl belirlenir?


34

Tek Sorumluluk İlkesi, yüksek uyum ilkesine dayanır. İkisi arasındaki fark, yüksek derecede yapışkan bir sınıfın, güçlü bir şekilde ilişkili olan bir dizi sorumluluk içermesidir; oysa, SRP'ye bağlı olan sınıfların yalnızca bir sorumluluğu vardır.

Ancak, belirli bir sınıfın bir takım sorumluluklar içerip içermediğini ve dolayısıyla sadece yüksek derecede uyumlu olup olmadığını veya yalnızca tek bir sorumluluğunun olup olmadığını ve dolayısıyla SRP'ye uyup uymadığını nasıl belirleriz? Başka bir deyişle, bazıları çok tanecikli bir sınıf olarak kabul edebileceğinden (ve sınıfın SRP'ye uyduğuna inanacağına göre), diğerleri yeterince tanecikli olmadığını düşünürken, az ya da çok öznel değil mi?



Yanıtlar:


21

Neden evet, bu çok öznel bir konu ve programcıların içine giren birçok ateşli, kırmızı yüzlü tartışmaların konusu.

Gerçekten bir cevap yok ve yazılımınız daha karmaşıklaştıkça cevap değişebilir. Bir zamanlar tek bir iyi tanımlanmış görev nihayetinde birden fazla tanımlanmamış görev haline gelebilir. Bu da hep ovalamadır. Bir programı görevlere ayırmanın doğru yolunu nasıl seçersiniz?

Verebileceğim tek tavsiye hakkında: şununla (ve iş arkadaşlarının) en iyi kararını kullan. Ve hatırlayın ki, hataları en kısa sürede yakalarsanız (genellikle) düzeltilebilir.


Keşke bilgisayar bilimi daha çok gerçek bilim gibiydi. Öznelliğin gerçek bilimde yeri yoktur. SOLID ilkeleri kendi başlarına iyi olmakla birlikte, öznelliği en aza indirmek ve nesnelliği en üst düzeye çıkarmak için yinelenmeleri gerekir. Bu henüz gerçekleşmedi, bu da gerçek dünyadaki meşruiyetlerini sorgulamamı sağlıyor.
DarkNeuron

13

SRP'nin ilk olduğu SOLID ilkelerini temel alan Bob Martin (Bob Amca), şunu söylüyor:

Bir sınıfın değişmesi için yalnızca bir nedeni olmalı

Birden fazla nedeni varsa, SRP'ye uymaz.


14
Bu sadece tanımı tekrar ediyor, ama aslında srp'ye bağlı kalmak hala oldukça öznel.
Andy

7

Sana birkaç kural verebilirim.

  • Sınıfı adlandırmak ne kadar kolay? Bir sınıfın isimlendirilmesi zorsa, muhtemelen çok fazla şey yapıyordur.
  • Sınıfın kaç ortak yöntemi var? 7 +/- 2 iyi bir kuraldır. Eğer sınıf bundan daha fazlasına sahipse, onu birkaç sınıfa bölmeyi düşünmelisiniz.
  • Ayrı bağlamlarda kullanılan ortak kamu yöntem grupları var mı?
  • Kaç tane özel yöntem veya veri üyesi var? Eğer sınıf karmaşık bir iç yapıya sahipse, muhtemelen iç kısımları daha küçük sınıflara paketlenecek şekilde yeniden yapılandırmalısınız.
  • Ve en basit kural: sınıf ne kadar büyük? Birkaç yüz satırdan uzun tek bir sınıf içeren bir C ++ başlık dosyanız varsa, muhtemelen ayırmalısınız.


7
7 +/- 2 hakkında kesinlikle katılmıyorum - tek sorumluluk ilkesi rastgele sayılarla değil, anlamsal uyumla ilgilidir.
JacquesB

1
Başparmak kuralının bağımsız bilimsel kanıtlara ihtiyacı yoktur. Modern bilimsel yöntem asırlık, mimarlık ve mühendislik bin yıllıktır. Genel metotlar için genel kural "birkaç" dır ve parametrelerin sayısı "birkaç" dır. Diğer yandan, bazı çocukların çizimleri aksini gösterse de, insanların kolları başlarından çıkmıyor [kaynak gösterilmeli].
abuzittin gillifirca

@CameronMartin Kurulumunuza bağlı olarak, bir sınıfın arayüzü okumanız için hazır olabilir veya olmayabilir. Kullanıcı arayüzü aramak, kod yazmakla neredeyse aynı değildir - her dakika belgelere bakmam gerekiyorsa, en azından, gerçek bir iş yapmak için harcadığım zamanı iki katına çıkarırım.
Daha temiz

6

Tek Sorumluluk İlkeleri, her yazılım modülünün değişmesi için tek bir neden olması gerektiğini söyler. Bob Amca'nın yakın tarihli bir makalesinde "değişme nedeni" açıklandı,

Ancak, bu prensibi düşündüğünüz gibi, değişimin nedenlerinin insanlar olduğunu unutmayın. Değişiklik isteyen insanlar. Ve birçok insanın farklı nedenlerden dolayı umursadığı kodu bir araya getirerek bu insanları veya kendinizi karıştırmak istemezsiniz.

Konsepti BURADA bir örnekle açıkladı .


Bu adam tarafından yazılmış harika bir makale.
MrDustpan,

4

Buna cevap vermek için bir adım geriye gidin ve tek sorumluluk ilkesinin amacını göz önünde bulundurun . Neden her şeyden önce önerilen bir tasarım prensibi?

İlkenin amacı kod tabanını "bölümlendirmek" tir, bu nedenle tek bir "sorumluluk" ile ilgili kod tek bir ünitede izole edilir. Bu, kodu bulmayı ve anlamayı kolaylaştırır ve daha da önemlisi, "sorumluluktaki" değişikliklerin yalnızca bir kod birimini etkileyeceği anlamına gelir.

Bir sistemde kesinlikle asla istemediğiniz şey, küçük bir şansın kodun görünüşte alakasız bir kısmının başarısız olmasına veya davranışını değiştirmesine neden olmasıdır. SRP, hataları ve değişiklikleri izole etmeye yardımcı olur.

Peki o zaman ne "sorumluluk"? Diğer değişikliklerden bağımsız olarak akla uygun bir şekilde değişebilecek bir şeydir. Bazı ayarları bir XML yapılandırma dosyasına kaydedebilen ve bunları dosyadan tekrar okuyabilen bir programınız olduğunu varsayalım. Bu tek bir sorumluluk mu, yoksa "yükle" ve "iki farklı sorumluluktan tasarruf" mu? Dosya biçiminde veya yapısında yapılacak her türlü değişiklik, hem yük hem de kaydetme mantığının değiştirilmesini gerektirir. Bu nedenle, tek bir sınıf tarafından temsil edilmesi gereken tek bir sorumluluktur. Şimdi bazı verileri CVS, Excel ve XML formatında dışa aktarabilecek bir uygulamayı düşünün. Bu durumda, bir formatın diğerini etkilemeden değişebileceğini hayal etmek kolaydır. Sınırlayıcıyı CVS formatında değiştirmeye karar verirseniz, Excel çıktısını etkilememelidir.


2

OO, sınıfların bir işlevsellik veri grubu olduğunu söylüyor. Bu tanım öznel yorumlama için çok fazla alan bırakır.

Sınıfların net ve kolay bir şekilde tanımlanması gerektiğini biliyoruz. Ancak, böyle bir sınıfı tanımlamak için, bir sınıfın genel tasarıma nasıl uyduğuna dair net bir fikre sahip olmak zorundayız. Paradoksal olarak, anti-patern olarak kabul edilen şelale türü gereklilikler olmadan ... bunu başarmak zordur.

MVC gibi çoğu durumda işe yarayan mimariye sahip bir sınıf tasarımı uygulayabiliriz. MVC uygulamalarında yalnızca veriye, bir kullanıcı arayüzüne ve ikisinin iletişim kurması için bir gereksinime sahip olduğumuzu varsayıyoruz.

Temel bir mimariyle, tek sorumluluk kurallarının ihlal edildiği durumları belirlemek daha kolaydır. EG Bir Kullanıcı Kontrolü örneğini bir Modal'a geçirme.


1

Sadece tartışma uğruna, ben bir sınıf getirecektir Juce denilen AudioSampleBuffer . Şimdi bu sınıf, bir snippet (veya belki de oldukça uzun bir snippet) ses parçası tutmak için var. Kanal sayısını, örnek sayısını (kanal başına) biliyor, değişken bir sayısal gösterime veya sözcük boyutuna sahip olmak yerine 32 bit IEEE yüzmeye bağlı görünüyor (ama bu benimle ilgili bir sorun değil). NumChannels veya numSamples ve pointer'ları herhangi bir belirli kanala almanıza izin veren üye fonksiyonlar vardır. Bir AudioSampleBuffer'ı daha uzun veya daha kısa yapabilirsiniz. İkincisi kesilirken eski sıfır-tamponları arabellek sanırım.

JUCE'nin kullandığı özel yığında yer ayırmak için kullanılan bu sınıfın birkaç özel üyesi var.

Ancak bu AudioSampleBuffer'ın eksik olduğu şeydir (ve Jules ile bu konuda birkaç tartışmam oldu): bir üye SampleRate. Bunu nasıl kaçırıyor olabilir?

Bir AudioSampleBuffer’ın yerine getirmesi gereken tek sorumluluk, numunelerinin temsil ettiğini duyduğu fiziksel sesi yeterince temsil etmektir. Bir AudioSampleBuffer'ı, bir ses dosyasını okuyan veya bir akıştan okuyan bir şeyden girdiğinizde, almanız ve AudioSampleBuffer ile birlikte almanız ve işlem yapması gereken bir yöntem olduğunu (bunun bir filtre olduğunu söylemesi) bilmesi gereken ilave bir parametre vardır. sonunda, bir yöntem ile oynar duyulmasını tampon üzerinden (veya başka bir yer için akarsu). Her neyse.

Ancak yapmanız gereken, AudioSampleBuffer'da yaşayan belirli seslere özgü olan bu SampleRate'i her yere iletmeye devam etmek. 44100.0f sabitinin bir fonksiyona geçtiği bir kod gördüm , çünkü programcı başka ne yapacağını bilemedi.

Bu, tek sorumluluğunu yerine getirememenin bir örneğidir.


1

Söylediklerinize dayanarak somut bir yolla yapılabilir - yüksek uyumun tek bir sorumluluğu sağladığına bağlılığı ölçebilirsiniz. Bir maksimum yapışkanlık sınıfı, tüm yöntemlerde kullanılan tüm alanlara sahiptir. Maksimum bir yapışkanlık sınıfı her zaman mümkün olmamakla birlikte, buna ulaşmak için hala en iyisi olması arzu edilirken. Bu sınıf tasarım hedefine sahip olmak, sınıfınızın birçok yöntem veya alana sahip olamayacağını (bazıları en fazla 7) söyleyemez.

Bir başka yol da, gerçek nesnelerden sonraki model olan OOP'un saf temellerindendir. Gerçek nesnelerin sorumluluğunu görmek çok daha kolaydır. Bununla birlikte, eğer gerçek nesne çok karmaşıksa, onu birden çok nesneyi kırmak, her birinin kendi sorumluluğuna sahiptir.

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.