Prinsip Tanggung Jawab Tunggal adalah tentang kode Anda hanya melakukan 1 hal dan Anda dapat membagi semua fungsionalitas dalam beberapa kelas yang semuanya dimaksudkan untuk melakukan 1 hal spesifik. Contohnya adalah kelas khusus untuk validasi, melakukan beberapa logika bisnis, memperkaya model, mengambil data, memperbarui data, navigasi, dll.
Separation of Concerns adalah tentang kode Anda yang tidak dipasangkan dengan erat ke beberapa kelas / sistem lainnya. Menggunakan antarmuka dalam kode Anda sangat membantu, dengan cara ini Anda dapat secara longgar menggabungkan beberapa kelas / sistem dengan kode Anda. Plusside dalam hal ini adalah lebih mudah untuk menguji unit Anda juga. Ada banyak kerangka kerja (IoC) yang dapat membantu Anda mencapai hal ini, tetapi tentu saja Anda dapat mengimplementasikannya sendiri juga.
Contoh sesuatu SoC, tetapi tidak memiliki SRP
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();
}
}
Seperti yang Anda lihat, kode ini tidak digabungkan dengan ketat ke kelas atau sistem lain, karena hanya menggunakan beberapa antarmuka untuk melakukan hal-hal. Ini bagus dari sudut pandang SoC.
Seperti yang Anda lihat kelas ini juga berisi 3 metode pribadi yang melakukan beberapa hal mewah. Dari sudut pandang SRP, metode-metode itu mungkin harus ditempatkan di dalam beberapa kelas mereka sendiri. 2 dari mereka melakukan sesuatu dengan navigasi, yang sesuai dengan beberapa kelas Navigasi. Yang lain melakukan beberapa perhitungan mewah pada suatu item, ini mungkin dapat ditempatkan dalam kelas IBusinessLogic.
Memiliki sesuatu seperti ini, Anda berdua memiliki SoC dan SRP di tempatnya:
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();
}
}
Tentu saja Anda bisa berdebat jika semua logika ini harus ditempatkan dalam GetDataAndNavigateSomewhereIfValid
metode ini. Ini adalah sesuatu yang harus Anda putuskan sendiri. Bagi saya sepertinya metode ini melakukan terlalu banyak hal.