Was ist der Unterschied zwischen dem Prinzip der Einzelverantwortung und der Trennung von Bedenken?


19

a) Was ist der Unterschied zwischen SRP und SoC ? Möglicherweise wird diese SRP auf Klassenebene angewendet, während SoC auf System- , Subsystem- , Modul- , Klassen- oder Funktionsebene angewendet werden kann.

b) Wenn die Antwort auf a) Ja lautet, wird dann SoC auf Klassenebene als Synonym für SRP angewendet ?

Danke dir

Antworten:


13

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 GetDataAndNavigateSomewhereIfValidMethode aufgenommen werden sollte. Das sollten Sie selbst entscheiden. Für mich sieht es so aus, als ob diese Methode viel zu viel Zeug macht.


"Nachdem ich den vollständigen Beitrag in JB Kings Antwort gelesen habe, denke ich, dass das auch ein guter Beitrag ist." Aber die Antwort von JB King behauptet das Gegenteil von Ihrer Antwort - nämlich, dass es bei SoC auch um die Einzelverantwortung geht, nur dass es auf höheren Ebenen angewendet werden kann als bei SRP
user1483278

2

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.


Wenn wir also davon ausgehen, dass SRP auch auf höheren Ebenen angewendet werden kann, besteht der Unterschied zwischen SRP und SoC darin, dass SRP eine einzige Verantwortung hat, während SoC eine Reihe eng verwandter Verantwortlichkeiten haben kann?
user1483278

@ user1483278: Nun, ich bin mit SRP sehr vertraut, habe aber beim Lesen dieser Frage zum ersten Mal von SoC gehört, sodass ich die Frage in Ihrem Kommentar nicht beantworten kann. Aus der Semantik geht es bei SRP anscheinend darum, dass Verantwortlichkeit und SoC voneinander getrennt sind. Ich weiß, dass dies eine umständliche Antwort ist, aber in der Anwendung führen störende Prinzipien zu ähnlichen Ergebnissen.
Gilles

0

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


0

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/

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.