Tek Sorumluluk İlkesi, kodunuzun sadece 1 şey yapmasıyla ilgilidir ve tüm işlevleri 1 belirli bir şey yapmak için tasarlanan birkaç sınıfta bölebilirsiniz. Örnek, doğrulama, bazı iş mantığı yapma, bir modeli zenginleştirme, veri alma, veri güncelleme, gezinme vb. İçin belirli bir sınıftır.
Endişelerin Ayrılması, kodunuzun diğer sınıflara / sistemlere sıkı sıkıya bağlı olmamasıyla ilgilidir. Kodunuzdaki arabirimleri kullanmak çok yardımcı olur, bu şekilde sınıfları / sistemleri kodla gevşek bir şekilde birleştirebilirsiniz. Bunun bir artı tarafı da kodunuzu birim olarak test etmenin daha kolay olmasıdır. Bunu başarmanıza yardımcı olabilecek çok sayıda (IoC) çerçeve var, ancak böyle bir şeyi elbette kendiniz de uygulayabilirsiniz.
SRP'ye sahip olmayan bir SoC örneği
public class Foo
{
private readonly IValidator _validator;
private readonly IDataRetriever _dataRetriever;
public Foo(IValidator validator, IDataRetriever dataRetriever)
{
_validator = validator;
_dataRetriever = dataRetriever;
}
public NavigationObject GetDataAndNavigateSomewhereIfValid()
{
var data = _dataRetriever.GetAllData();
if(_validator.IsAllDataValid(data))
{
object b = null;
foreach (var item in data.Items)
{
b = DoSomeFancyCalculations(item);
}
if(_validator.IsBusinessDataValid(b))
{
return ValidBusinessLogic();
}
}
return InvalidItems();
}
private object DoSomeFancyCalculations(object item)
{
return new object();
}
private NavigationObject ValidBusinessLogic()
{
return new NavigationObject();
}
private NavigationObject InvalidItems()
{
return new NavigationObject();
}
}
Gördüğünüz gibi, bu kod sınıflara veya diğer sistemlere sıkıca bağlı değildir, çünkü bir şeyler yapmak için sadece bazı arayüzleri kullanır. Bu bir SoC açısından iyidir.
Gördüğünüz gibi bu sınıf bazı süslü şeyler yapan 3 özel yöntem de içeriyor. Bir SRP açısından bakıldığında, bu yöntemler muhtemelen kendi sınıflarına yerleştirilmelidir. 2 tanesi bazı INavigation sınıfına uyan navigasyon ile bir şeyler yapıyor. Diğeri bir öğe üzerinde bazı süslü hesaplamalar yapar, bu muhtemelen bir IBusinessLogic sınıfına yerleştirilebilir.
Böyle bir şeye sahipken, ikinizde de SoC ve SRP var:
public class Foo
{
private readonly IValidator _validator;
private readonly IDataRetriever _dataRetriever;
private readonly IBusinessLogic _businessLogic;
private readonly INavigation _navigation;
public Foo(IValidator validator, IDataRetriever dataRetriever, IBusinessLogic businessLogic, INavigation navigation)
{
_validator = validator;
_dataRetriever = dataRetriever;
_businessLogic = businessLogic;
_navigation = navigation;
}
public NavigationObject GetDataAndNavigateSomewhereIfValid()
{
var data = _dataRetriever.GetAllData();
if(_validator.IsAllDataValid(data))
{
object b = null;
foreach (var item in data.Items)
{
b = _businessLogic.DoSomeFancyCalculations(item);
}
if(_validator.IsBusinessDataValid(b))
{
return _navigation.ValidBusinessLogic();
}
}
return _navigation.InvalidItems();
}
}
Elbette tüm bu mantığın GetDataAndNavigateSomewhereIfValid
yönteme dahil edilmesi gerekip gerekmediğini tartışabilirsiniz . Bu kendiniz karar vermeniz gereken bir şey. Bana göre bu yöntem çok fazla şey yapıyor gibi görünüyor.