Giriş Giriş Giriş
Tek Sorumluluk Prensi (SRP), nesne odaklı tasarım ilkelerinden biridir, Robert C. Martin tarafından ilk formüle edilen ve SRP, her sınıf veya modüllerin tam olarak bir şekilde değişmesi gerektiğini belirtir ve bir sınıfın ilgili işlevsellikte hataları tanıtabilir.Bu kırılganlık, test etmek ve evrimleşmek için kod tabanını daha zor hale getirir.
Basitliğine rağmen, SRP genellikle gerçek dünya kodunda ihlal edilir. Gemiye baskı hızla, belirsiz alan sınırları ile birlikte, sık sık sık sık sık sık sık sık sık sık sık sık sık sık sık sık sık sık sık sık sık sık sık sık sık sık sık sık, bu makale, SRP ihlallerinin, pratik algılama stratejilerinin ve endişelerinin temizlenmesini sağlamak için yeniden faktörleme teknikleri ile bir araya gelir.
Tek Sorumluluk Prensibini Anlamak
Tam olarak bir Sorumluluk Nedir?
Martin'e göre, bir sorumluluk şöyledir:0)Değişme nedeni[Dönetici:0))[değiştir | kaynağı değiştir].Bir sınıf, bir “ve” kullanarak, “bu sınıf doğrulama şekline sahiptir; örneğin, “bu sınıf bir ücretle iletişim kurma işlemine sahiptir; e-posta yoluyla faturayı gönderir.
SRP, sınıf boyutunu sınırlamak veya yöntemleri ortadan kaldırmakla ilgili değildir. Her sınıfın iyi tanımlanmış bir odaklanması gerekir. Tek bir tek, koherent sorumluluğu (örneğin, karmaşık bir iş işlemi) ile ilgili olarak, küçük bir sınıftan daha iyidir.
SRP Nedenleri
- [FONT:0]Maintainability:[Dönetici:[Dönetici:0)[Dönetici:0)[Dönetici:[Dönetici:0)[Dönetici:[Dönetici: 0 ) Her sınıf bir değişiklik için bir nedeni olduğunda, değişiklikler izole edilir. e-posta gönderme mantığına bir değişiklik fatura formatlama mantığını bozma riskini doğurur.
- [FONT:0)Testability:[Dönetici:[Dönetici:0)Testability:[Döneticileri)[Döneticileri test etmek daha kolaydır.
- [FONT:0)Reusability:[Dönetici:[Dönetici:0) Odaklı bileşenler sistemin farklı bölgelerinde veya diğer projelerde yeniden kullanılabilir. genel amaçlı bir formatta belirli bir teslimat mekanizmasına çift olmamalıdır.
- [FONT:0]Parallel Development:[Döneticiler, sınıfların açıkça silindiği minimum bir birleşme çatışmaları ile aynı anda ayrı sorumluluklar üzerinde çalışabilirler.
SRP Violations
SRP ihlalleri genellikle gözlemlenebilir kod kokuları ile ortaya çıkıyor. Bu kokular mutlak bir kanıt değil, ancak bir sınıfın çok fazla endişe aldığını şiddetle tavsiye ediyorlar.
1. Büyük, Komplek Sınıflar
Yüzlerce veya binlerce çizgiyi kapsayan bir sınıf, birçok alanı ve yöntemi içeriyor ve yüksek bir cyclomatic karmaşıklığı hem veritabanını sorgular, onay e-postalarını yayınlar ve denetim izlerini gördüğünüzde, en az dört farklı sorumluluka sahip.
2. Değişim için Çoklu Farklı Sebepler
Kendinize sorun: “Bu sınıfın değiştirilebilmesine neden olabilir?” Liste, ilgili bir nedenden daha fazlasını içeriyorsa – e-posta formatında yeni bir veritabanı şeması, farklı bir giriş çerçevesi – sonra sınıf SRP’yi ihlal eder.Her bir sebepten dolayı kendi sınıfında ortaya çıkmalı ayrı bir endişeye karşılık gelmelidir.
3. Kod Duplication Across Methods
Aynı mantık aynı sınıfta birden çok yöntemde ortaya çıktığında, bu yöntemlerin farklı sorumluluklara ait olduğunu sıklıkla gösterir. Örneğin, “save” ve “export” yöntemleri aynı geçerlilik kodu içeriyorsa, bu doğrulama kendi geçerli sınıfına çıkarılması gereken ayrı bir sorumluluktur.
4. Zor veya İmkansız Birim Testleri
Bir sınıf için bir birim testi yazmak ayrıntılı bir fikstür kurmak gerektirir - bir veritabanı, bir dosya sistemi, bir e-posta sunucusu ve üçüncü taraf API - sınıf muhtemelen çok fazla sorumluluk alır. Gerçek bir birim testi sadece bir veya iki bağımlılıkla alay ederek tek bir davranışı test edebilir.
5. Frequent ve Tahmin edilemez Değişiklikler
Her iterasyona göre değiştirilmiş sınıflar, genellikle farklı nedenlerle, “değişim darbesi” bir değişiklik yanlışlıkla başka bir şeyi etkiler. Bu istikrarsızlığın SRP ihlallerinin bir salon işaretidir. Dosyanızın versiyonunu izleyin; eğer tek bir sınıf farklı kullanıcı hikayelerine hitap ederse, kırmızı bir bayraktır.
6. Uzun Para Listeleri veya Aşırı Tesis Yöntemleri
Kullanılmadan önce birçok parametreye ihtiyaç duyan sınıflar, birden çok bağlamı çözmeye çalıştıklarını göstermektedir. Benzer şekilde, belirli bir sırayla çağrılabilen sayısız kamu setleriyle sınıf (temporal darbe) farklı sorumlulukların birlikte karıştırıldığını göstermektedir.
Tartışmaları Tanımlamak için Stratejiler
Bir Checklist ile Kılavuz Kodu Yorumlar
Kod incelemeleri sırasında, belirli sorular sor: “Bu sınıfın tek sorumluluğu nedir?” Eğer takım bir koncise cevabı konusunda hemfikir değilse, sınıf muhtemelen yukarıdaki işaretleri içeren bir kontrol listesi kullanın. Encourage reviewers to Flag any method that appears a method that performs network I/O in a class öncelikle ilgili.
Statik Kod Analizi Araçları
Otomatik araçlar birçok SRP kokularını yapılandırılabilir kurallarla tespit edebilir. İşte dikkate alınması gereken bazı ölçümler ve araçlar:
- [FONT=0)Cyclomatic Kompleksi:[Dönetici:[Dönetici: 1 ) Yüksek karmaşıklık ile yöntemler genellikle birden fazla sorumluluk işaret eder.|Üye Olmayanlar[DÜye Olmayanlar İçindekiler:2).SonarQube).
- [FONT=0)Pekizasyon (LCOM): Bu ölçümler, sınıf aslında farklı veriler üzerinde çalışan birkaç farklı yöntem içeriyor - net bir SRP ihlali. birçok statik analizcüler, örneğin [[D, LCOM değeri LCOM.
- [FONT=0]Kıd Fan-Out:[DÜDÜT:1] Bir sınıf diğer ilgili sınıflara bağlıysa, çok fazla sorumluluk orkestrası olabilir. SonarQube “afferent coupling” ve “efferent darbesi” .
- [FONT:0)Kodul Tespiti:[Dönetici:0)[Dönetici:0) veya SonarQube'deki yerleşik duplikasyon dedektörü, çıkarılan blokları tekrarlayabilir.
Bağımlılık Graph Analysis
Sınıflarınız arasındaki bağımlılıkları görselleştirmek. Düşük seviyeli bir fayda sınıfı yüksek seviyeli iş mantığına (bir bağımlılık döngüsü veya birçok bağlantı ile “hub”a bağımlıdır), SRP muhtemelen bu ilişkileri görmenize yardımcı olur.
Kuru Runs Yeniden Yardımcı Etmek
Değişiklikler yapmadan önce, şüpheli bir sınıf yeniden faktör etmeye çalışın. Farklı yöntemleri ve alanları birlikte ait gibi görünen alanları tanımlayın.Her grubu tek bir nounla (örneğin, “ReportFormatter”, “EmailSender”, “DatabaseAccessor”), o zaman orijinal sınıf kod yazmadan bile açık sınırlar ortaya koyar.
SRP'yi geri yüklemeye yardımcı olmak
Bir ihlal tespit ettikten sonra, hedef, sınıfın daha küçük, odaklanmış sınıflara, mevcut davranışı korurken yeniden faktörlemenin her adımdan sonra geçen testler ile artması gerekir.
Sınıf Türlü
En doğrudan teknik: her biri için yeni bir sınıf oluşturmak ve ilgili yöntemleri ve alanları ona taşımak. Orijinal sınıf o zaman yeni sınıflara olegeler olur. Zamanla, façade'yi kaldırabilirsiniz ve müşterilerin doğrudan küçük sınıflarla etkileşime girmesine izin verebilirsiniz. Örneğin, eğer birFLT:1 hem kimlik doğrulama hem de profil güncellemelerini ele alırsa, alıntılar:2).
Polimorphism ile Durumsal Değiştirin
Bir sınıf birçok [[DörtÜ4) veya DÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜ
Ayrı İletişim ve İşleme
Her iki işlem sonucu hesaplamak ve bazı kanal aracılığıyla göndermek (network, file, UI) SRP'yi ihlal ediyor. Hesaplama ve iletişim iki ayrı sorumluluktur. Komut/Query modeli kullanın: bir hizmet nesnesi hesaplamayı gerçekleştirir ve bir özel hediye veya gönderme yapar.Bu, çıktı kanalına alay etmeden hesaplamayı yapar.
Bir Event System Tanıyın
Bir sınıf yan etkileri (kesinlikle, bildirim, denetim) bir temel operasyondan sonra tetikleyebilmek için ihtiyaç duyduğunda, SRP bu yan etkileri ortaya koyar. Bir etkinlik odaklı yaklaşım, temel sınıfın bir olayı yayınlamasını sağlar ve ayrı eller giriş, e-postalamadan sorumludur.
Pratik Örnek: Bir RaporGenerator Sınıfı Yeniden Yardımcı Etmek
Bir sınıf düşünün:
- Bir veritabanından gelen Fetches verileri
- Veriler HTML'ye göre biçimlendirir
- E-postalar, alıcıların listesine rapor
- Girişi bir dosyaya gönder
Bu sınıf açıkça dört sorumluluka sahiptir. Zamanla, farklı nedenlerle her sorumluluk değişiklikleri: yeni veri kaynakları, yeni çıktı biçimleri, yeni e-posta sağlayıcıları, yeni giriş standartları. Sınıf çokça bir adım önde gelen yeniden faktörleme planıdır.
Adım 1: Sorumlulukları Tanımlayın
Değişim nedenleri listesi: veritabanı şema değişiklikleri, formatlama gereksinimleri, e-posta teslimat mantığı, log formatı.Her biri ayrı bir endişedir.
Adım 2: Data Access
Sorgulayan bir sınıf oluşturun. Veritabanı bağlantısını ve sorgu mantığını içine taşıyın.The originalurFLT:8) Bu havuza delegeler.
Adım 3: Formatting
Çiğ veri gerektiren ve bir HTML dizesini geri getiren bir sınıf oluşturun.TheurFLT:10 şu anda veri almak için depoları çağırır, sonra HTML oluşturmak için formatter.
Adım 4: E-posta Gönder
BirFLT:11 oluşturun, e-posta mesajları hazırlamak ve göndermekten sorumlu bir sınıf. Bu sınıf, bir e-posta sunucusu yapılandırmasına bağlıdır, rapor verilere veya formatlamalara bağlı değildir.
Adım 5: Ekstraksiyon Logging
Kayıt sonuçları için standart bir giriş çerçevesi oluşturmak için bir uyarı oluşturmak için bir etkinlik oluşturabilirsiniz. e-posta servisi logger diyebilir, ancak daha iyi bir olay kullanabilir: Başarılı bir göndermeden sonra, ayrı bir log eller topladığı bir olay yükseltebilirsiniz.
Sonuç Sonuç Sonuç Sonuç
OrijinalFL: 9) bir koordinatör (veya tamamen ortadan kaldırılır) Her yeni sınıf küçük, test edilebilir ve değiştirmek için tek bir nedene sahiptir. Örneğin, bir veritabanı veya e-posta sunucusu olmadan birim test edilebilir.
Ongoing Vigilance için Araçlar ve Metrikler
Sürekli entegrasyon hattınıza SRP algılamasını entegre edin. kod kalitesini takip etmek için aşağıdaki ölçümleri kullanın:
- [FONT:0) Yöntem başına Cyclomatic Kompleksity:[DDDD: 1) En fazla yöntemler için 10'un altında değerler için Aim.
- [DIT:0) Inheritance Tree (DIT): [DFLT:1) Çok derin miras, sınıfların odaklandığı miras üzerinde kompozisyonu saklayabilir.
- [Üyetim:0)LCOM (Sekizlemenin Cohesionı:[Döneticileri): [Döneticileri bunu hesaplamak için birçok statik analiz cihazı bunu hesaplamak için bir değer) sınıf bölmesi gerektiğini gösterir.
- [FONT:0]Number of Direct Dependencies: Bir sınıf, ilgili olmayan bir avuçdan daha fazla bağlıysa, birçok sorumlulukta muhtemelen koordinatörleri olur.
Popüler araçlar:0)SonarQube[[Dönetici:0) PHP ile kapsamlı bir pano sunuyor. ).[Döneticileri için 8 ° C) için .NET, bağımlılık grafiği ve kod kuralları sunar.[Döneticileri[Döneticileri için).).
Refaksiyonda Ortak Pitfalls
SRP'ye yeniden faktörleme risksiz değildir:
- [FONT:0)Genellikle: [Dönetici: [Dönetici: 0] Bölünme sınıfları erkenden ihtiyaçsız soyutlama yaratabilir. nadiren değişikliklere ihtiyaç duymamış bir sınıf, iki içsel endişeye sahip olsa bile yeniden faktörlemeye ihtiyaç duymaz.
- [FONT:0) Increased Iny:[Dönlendirmede][Dönlendirmede] çok sayıda küçük sınıf, sistemin gezinmesi zor hale gelebilir. Denge anahtardır - her sınıf net bir isim ve amacı olmalıdır.
- [FONT:0)Performance ins:[Döneticileri değiştir] Sorumluluklarını genellikle daha önce ve sonra ekstra bir heyet katmanı ekliyor; genel olarak, kullanılabilirlik kazancı ile kıyaslanamaz.
- [FONT:0) Tamamlayıcı:[Dönetici:[Dönetici:0)[Dönetici:0) Tamamlanan bir mirastan vazgeçerek, ancak birçok sınıfla ilgili olarak, en sonunda, müşteriler yeni iyi sınıf sınıf sınıflara bağlı olmalıdır.
Sonuç Sonuç Sonuç Sonuç Sonuç Sonuç Sonuç Sonuç
Single Sorumluluk Prensipleri Tanımlama ve düzeltme, yazılım kalitesinde kar kar kar kar payı ödeyen sürekli bir disiplindir.SRP'nin kılavuzluk olduğunu hatırlayın - büyük sınıflar, çok sayıda nedeni değiştirmek, sert test edilebilir ve erken bir şekilde adapte olabilirsiniz. Her sınıf iyi bir şey olduğunda, sisteminiz daha kolay ve daha az yatkın hatalarınıza eğilimli hale gelir.
Martin Fowler'in yazdığı gibi:0)Refaksiyon: Mevcut Kod Tasarımının iyileştirilmesi[[[Dönetici: 1), “Herhangi bir aptal, insanların anlayabileceğini kod yazabilir. İyi programcılar SRP'ye başvurabilmek, insanların zaman testini engelleyen en etkili yollardan biridir.