Принцип единой ответственности заключается в том, что ваш код выполняет только одну задачу, и вы можете разделить всю функциональность на несколько классов, которые предназначены для выполнения одной конкретной задачи. Примером является конкретный класс для проверки, выполнения некоторой бизнес-логики, обогащения модели, извлечения данных, обновления данных, навигации и т. Д.
Разделение проблем заключается в том, что ваш код не тесно связан с некоторыми другими классами / системами. Использование интерфейсов в вашем коде очень помогает, таким образом вы можете свободно связывать классы / системы с вашим кодом. Плюсом этого является то, что ваш код также проще для модульного тестирования. Существует множество (IoC) фреймворков, которые могут помочь вам в этом, но вы, конечно, можете реализовать и это самостоятельно.
Пример чего-то SoC, но не имеющий 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();
}
}
Как вы можете видеть, этот код не тесно связан с классами или другими системами, потому что он использует только некоторые интерфейсы для работы. Это хорошо с точки зрения SoC.
Как вы можете видеть, этот класс также содержит 3 приватных метода, которые делают некоторые интересные вещи. С точки зрения SRP, эти методы, вероятно, должны быть помещены в некоторые собственные классы. 2 из них делают что-то с навигацией, что вписывается в некоторый класс INavigation. Другой выполняет некоторые необычные вычисления для элемента, возможно, его можно поместить в класс IBusinessLogic.
Имея что-то вроде этого, у вас обоих есть SoC и SRP:
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();
}
}
Конечно, вы могли бы спорить, следует ли поместить всю эту логику в GetDataAndNavigateSomewhereIfValid
метод. Это то, что вы должны решить для себя. Мне кажется, что этот метод делает слишком много вещей.
Что касается применения SRP только на уровне класса, то в своих книгах Роберт К. Мартин (насколько я знаю, он популяризировал, если не придумал концепцию) утверждает:
Чистый код, страница. 138 : «Принцип единой ответственности (SRP) гласит, что у класса или модуля должна быть одна и только одна причина для изменения».
В Agile Принципы, Образцы и Практики в C #, стр. 116 : «[...] и связывайте сплоченность с силами, которые вызывают изменение модуля или класса».
Акцент мой.
В APPP он более подробно рассказывает о SRP и почти полностью сосредоточен на уровне класса. Хотя он, кажется, сосредотачивается на уровне класса, я чувствую, что принцип также направлен на модули и другие конструкции более высокого уровня.
По этой причине я бы не квалифицировал SRP как SoC на уровне класса, как вы предлагаете в своем вопросе.
источник
Здесь вы можете найти короткое видео, объясняющее разницу между этими терминологиями. https://www.youtube.com/watch?v=C7hkrV1oaSY
Разделение концернов (SoC). Разделите ваше приложение на отдельные функции с минимальным дублированием функций. (Microsoft).
«Концерн» = «отличительный признак» = «отдельный раздел»
«Концерн» работает как на высоком, так и на низком уровне
Принцип единой ответственности гласит, что каждый модуль или класс должен нести ответственность за одну часть функциональности, предоставляемой программным обеспечением, и эта ответственность должна быть полностью заключена в класс. Все его услуги должны быть тесно связаны с этой ответственностью. (Определение Википедии)
«Ответственность» = «причина для изменения»
изменить что? «Отдельная часть функциональности, предоставляемой программным обеспечением» = Базовая единица
Вывод
Принцип единой ответственности работает на базовых единицах -> работает на низком уровне
Разделение концернов работает как на высоком, так и на низком уровнях.
SRP и SoC работают вместе для разделения проблем. Они точно такие же на низком уровне
источник
Вот мое понимание этих принципов.
Разделение проблем (SoC) - это разделение программной системы на более мелкие модули, каждый из которых отвечает за одну проблему. В данном случае проблемой является функция или вариант использования программной системы. Модуль имеет четко определенный API (интерфейс), в результате чего вся система становится очень сплоченной. Существует два основных типа: горизонтальный и вертикальный.
Принцип единой ответственности (SRP) - это принцип проектирования, который гласит, что каждый строительный блок (это может быть класс, модуль, объект или даже функция) системы должен нести только одну ответственность. Роберт С. Мартин. Мартин описывает ответственность как причину перемен. В целом, гораздо лучше иметь один класс / объект, который отвечает за одну часть функциональности, а не выполнять множество, иногда даже не связанных функций, что делает этот класс большим и тесно связанным, поэтому называется «объект Бога».
Также я описал эти принципы более подробно в своем блоге, пожалуйста, посмотрите.
https://crosp.net/blog/software-architecture/srp-soc-android-settings-example/
источник