Das Prinzip der Einzelverantwortung bezieht sich darauf, dass Ihr Code nur eine Aufgabe erfüllt. Sie können alle Funktionen in mehrere Klassen aufteilen, die alle für eine bestimmte Aufgabe vorgesehen sind. Ein Beispiel ist eine bestimmte Klasse zur Validierung, zum Ausführen von Geschäftslogik, zum Anreichern eines Modells, zum Abrufen von Daten, zum Aktualisieren von Daten, zur Navigation usw.
Bei der Trennung von Bedenken geht es darum, dass Ihr Code nicht eng an andere Klassen / Systeme gekoppelt ist. Die Verwendung von Schnittstellen in Ihrem Code hilft sehr, auf diese Weise können Sie Klassen / Systeme locker mit Ihrem Code koppeln. Ein Pluspunkt dabei ist, dass es einfacher ist, Ihren Code auch als Unit zu testen. Es gibt viele (IoC-) Frameworks, die Ihnen dabei helfen können, aber Sie können so etwas natürlich auch selbst implementieren.
Ein Beispiel für etwas SoC, aber ohne 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();
}
}
Wie Sie sehen können, ist dieser Code nicht eng an Klassen oder andere Systeme gekoppelt, da er nur einige Schnittstellen verwendet, um Dinge zu erledigen. Dies ist vom Standpunkt des SoC aus gesehen gut.
Wie Sie sehen können, enthält diese Klasse auch 3 private Methoden, die ausgefallene Dinge tun. Aus SRP-Sicht sollten diese Methoden wahrscheinlich in eigene Klassen eingeordnet werden. 2 von ihnen tun etwas mit der Navigation, was in eine Navigationsklasse passen würde. Der andere führt einige ausgefallene Berechnungen für ein Element durch, dies könnte wahrscheinlich in eine IBusinessLogic-Klasse eingefügt werden.
Wenn Sie so etwas haben, haben Sie beide den SoC und den SRP installiert:
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();
}
}
Natürlich könnte man diskutieren, ob all diese Logik in die GetDataAndNavigateSomewhereIfValid
Methode aufgenommen werden sollte. Das sollten Sie selbst entscheiden. Für mich sieht es so aus, als ob diese Methode viel zu viel Zeug macht.
Zu SRP, das nur auf Klassenebene angewendet wird, schreibt Robert C. Martin in seinen Büchern (soweit ich weiß, dass er das Konzept populär gemacht hat, wenn er nicht darauf gekommen ist):
Code bereinigen, Seite. 138 : "Das Einzelverantwortungsprinzip (Single Responsibility Principle, SRP) besagt, dass eine Klasse oder ein Modul einen und nur einen Änderungsgrund haben sollte."
In Agile-Prinzipien, -Muster und -Praktiken in C #, Seite 116 : "[...] und Beziehen Sie den Zusammenhalt auf die Kräfte, die bewirken , dass sich ein Modul oder eine Klasse ändert."
Betonung meiner.
In APPP spricht er ausführlicher über SRP und konzentriert sich fast ausschließlich auf die Klassenebene. Während er sich anscheinend auf die Klassenebene konzentriert, ist das Prinzip meines Erachtens auch auf Module und andere Konstrukte höherer Ebenen gerichtet.
Aus diesem Grund würde ich SRP auf Klassenebene nicht als SoC qualifizieren, wie Sie in Ihrer Frage vorschlagen.
quelle
Hier finden Sie ein kurzes Video, das den Unterschied zwischen diesen Begriffen deutlich macht. https://www.youtube.com/watch?v=C7hkrV1oaSY
Trennung von Anliegen (SoC). Teilen Sie Ihre Anwendung in verschiedene Funktionen mit möglichst geringer Funktionsüberschneidung ein. (Microsoft).
"Anliegen" = "Besonderes Merkmal" = "Besonderer Abschnitt"
"Sorge" funktioniert sowohl auf hoher als auch auf niedriger Ebene
Prinzip der Einzelverantwortung besagt, dass jedes Modul oder jede Klasse die Verantwortung für einen einzelnen Teil der von der Software bereitgestellten Funktionalität tragen sollte und dass die Verantwortung vollständig von der Klasse eingekapselt werden sollte. Alle seine Dienstleistungen sollten eng mit dieser Verantwortung verbunden sein. (Wikipedia-Definition)
"Verantwortung" = "Grund zur Veränderung"
was ändern? "Ein einzelner Teil der von der Software bereitgestellten Funktionalität" = Basiseinheit
Fazit
Das Prinzip der Einzelverantwortung wirkt auf Basiseinheiten -> arbeitet auf niedriger Ebene
Die Trennung von Bedenken funktioniert sowohl auf hoher als auch auf niedriger Ebene
SRP und SoC arbeiten bei der Trennung von Anliegen zusammen. Sie sind auf niedrigem Niveau genau gleich
quelle
Hier ist mein Verständnis dieser Prinzipien.
Separation of Concerns (SoC) - ist die Aufteilung eines Softwaresystems in kleinere Module, wobei jedes dieser Module für ein einzelnes Unternehmen verantwortlich ist. Ein Problem ist in diesem Fall eine Funktion oder ein Anwendungsfall eines Softwaresystems. Ein Modul verfügt daher über eine genau definierte API (Schnittstelle), die ein Gesamtsystem in hohem Maße zusammenhält. Es gibt zwei Haupttypen: horizontal und vertikal.
Single Responsibility Principle (SRP) - ist ein Entwurfsprinzip, das besagt, dass jeder Baustein (es kann sich um eine Klasse, ein Modul, ein Objekt oder sogar eine Funktion handeln) eines Systems nur eine einzige Verantwortung haben sollte. Robert C. Martin. Martin beschreibt eine Verantwortung als Grund zur Veränderung. Im Allgemeinen ist es viel besser, eine einzelne Klasse / ein einzelnes Objekt zu haben, das die Verantwortung für einen einzelnen Teil der Funktionalität trägt, als in der Lage zu sein, viele, manchmal sogar nicht zusammenhängende Funktionen auszuführen, wodurch diese Klasse groß und eng gekoppelt wird. genannt "Gott Objekt".
Auch diese Prinzipien habe ich in meinem Blogeintrag ausführlicher beschrieben, schauen Sie doch mal rein.
https://crosp.net/blog/software-architecture/srp-soc-android-settings-example/
quelle