Verstoßen Setter und Getter immer gegen das Prinzip der Einzelverantwortung?

8

Wie wir wissen, besagt die SRP, dass jede Klasse eine einzige Verantwortung haben sollte und dass die Verantwortung vollständig von der Klasse gekapselt werden muss.

Aber Getter und Setter tun eine andere Verantwortung dienen - sie tun abstrakte Klasse Eigenschaft (Daten) Zugang.

Wenn Setter und Getter auf abstrakte Klasseneigenschaften zugreifen, dienen sie einer anderen Verantwortung .

Also, wenn ich so etwas habe,

class Config
{

    private location;


    public function write(array $data)
    {
        ....
    }

    public function read($key)
    {
        ...
    }

    public function exists($key)
    {
        ...
    }

    public function delete($key)
    {
        ...
    }

    // Below comes property abstraction

    // Here I doubt - I CANNOT USE this class without them
    // but they seem to break the SRP at the same time!?

    public function setFileLocation($location)
    {
        $this->location = $location;
    }


    public function getFileLocation()
    {
        return $this->location;
    }


    public function setConfigArray(...)
    {
        ...
    }

    public function getConfigArray()
    {
        ...
    }
}

Ich breche die SRP. Das Problem ist, dass nur so eine Klasse existieren kann.

Die Frage ist also:

In meiner Situation ist es fast unmöglich zu vermeiden setFileLocation()und getFileLocation()mit CRUD diejenigen Methoden.

Wenn ich also durch die Kombination von CRUD-Methoden mit der Datenzugriffsabstraktion die SRP unterbreche,

Gibt es eine Möglichkeit, die SRP einzuhalten und gleichzeitig das gemeinsame Konzept der Config-Klasse (CRUD-Operationen) beizubehalten?

Yang
quelle
1
@metal_fan: Sie brechen genau so viele Funktionen, wenn Sie ein öffentliches Mitglied haben oder wenn Sie ein privates Mitglied mit trivialem öffentlichen Getter und Setter haben. Und ich sage genau so viel, weil es in einigen Fällen keine und in anderen alle sein kann. Abhängig davon, ob ihre Verwendung interne Invarianten brechen kann.
Jan Hudec
1
Was ist die Verantwortung der Konfigurationsklasse, wenn sie keinen zentralen Ort zum Speichern und Abrufen dieser Konfigurationswerte bereitstellen soll? Ist SRP in jeder Datenbank kaputt? In dem Beispiel, das Sie verknüpfen, gibt es zwei Verantwortlichkeiten: 1 ist Getter und Setter, 2 ist CRUD. In dem Beispiel, das Sie posten, gibt es kein CRUD, daher gibt es nur 1 Verantwortung.
Trylks
" Sie haben das Wahre und das Reale verwechselt. " - George Stanley im Gespräch, zitiert von Samuel R Delany

Antworten:

11

Ehrlich gesagt denke ich, dass Sie das Konzept der Einzelverantwortung etwas zu weit führen. Getter und Setter sind für das Funktionieren der Klasse von Bedeutung, unabhängig davon, ob Sie dies durch direkten Zugriff auf öffentliche Mitglieder tun oder Methoden (oder Eigenschaften) verwenden, um dies zu tun.

Sie machen das Argument, dass das Erhalten und Setzen eines Mitglieds der Klasse eine separate Verantwortung ist und daher an einen anderen Ort verlegt werden sollte. Nehmen wir an, wir machen das, und jetzt haben Sie Klassen namens Configund ConfigAccessor. Zu diesem Zeitpunkt haben Sie jetzt einen Luftspalt zwischen den beiden Klassen, da Configkeine Schnittstelle für den Zugriff auf das locationMitglied vorhanden ist. Das macht es unmöglich zu schreiben ConfigAccessor, und Sie haben eine unveränderliche, einmal schreibende Klasse, die überhaupt keinen Nutzen hat. Wenn Sie eine Art Schnittstelle hinzufügen, um ConfigAccessorihre Arbeit zu erledigen, haben Sie ein rekursives Problem.

Die SRP ist, wie viele andere Dinge in diesem Bereich, ein Prinzip, keine feste Regel. Das bedeutet, dass Sie Ihre Situation beurteilen sollten, anstatt zu versuchen, sie bedingungslos zu befolgen. Es gibt eine Grenze zwischen Purist sein und die Arbeit erledigen, und wenn Ersteres Letzteres verhindert, sind Sie auf der falschen Seite.

Wenn ich Ihr Design ein wenig kritisieren kann: Wenn Ihre ConfigKlasse als Schnittstelle zwischen einer auf der Festplatte gespeicherten Konfigurationsdatei und Ihrem Code konzipiert ist, möchten Sie als letztes den Speicherort im Midstream ändern. Wenn Sie das ändern, um den locationZugriff auf eine andere Datei zu starten, sollten Sie das alte Objekt zerstören und ein neues erstellen. Sie haben nicht klargestellt, ob Sie den Inhalt der Datei im Objekt speichern möchten. Wenn Sie damit den Inhalt einer Konfigurationsdatei inhalieren und in eine andere schreiben möchten, sollten Sie eine Methode verwenden, mit der die Daten in ein neues Objekt geklont werden, das auf die neue Datei verweist.

Blrfl
quelle
4

Es gibt zwei verschiedene Ebenen, auf denen Sie die SRP anwenden können.

Die erste Ebene ist die Ebene der einzelnen Funktionen / Methoden. Jeder sollte nur eine Aufgabe ausführen (und nach den Methodennamen zu urteilen, keine der Methoden, Configum die SRP zu brechen).

Die zweite Ebene ist die Ebene einer Klasse. Hier wird das Konzept einer einzelnen Verantwortung etwas abstrakter, aber ein guter Indikator ist, wenn Sie die Verantwortlichkeiten einer Klasse in einem Satz ohne die (implizite) Verwendung des Wortes und angeben können . Wenn Sie dies mit der Anwesenheit der Getter und Setter tun können, bricht die Klasse die SRP nicht.

Im Allgemeinen Getter und, in geringerem Maße, Einrichter sind jedoch ein Hinweis darauf , dass die Einkapselung einer Klasse gebrochen. Im Fall der ConfigKlasse ist die setFileLocationMethode gut, da sie Configeine Möglichkeit benötigt, um herauszufinden, wo sich die Daten befinden. Die anderen scheinen jedoch verdächtig zu sein, da sie Informationen offenlegen, die Benutzer Confignicht benötigen sollten.

Bart van Ingen Schenau
quelle
4

Ihre Konfigurationsklasse hat die Verantwortung, die Konfiguration zu verfolgen, indem private Verweise auf bestimmte Daten gespeichert und über Mutator-Methoden Zugriff darauf gewährt werden. Dies bricht die SRP nicht, da die Klasse selbst immer noch eine einzige Verantwortung hat . Die Mutatoren helfen ihm lediglich dabei, diese Verantwortung zu erfüllen, indem sie den Zugriff auf die Daten abstrahieren. Die Mutatoren haben keine andere Verantwortung als die der Klasse. Sie sind Teil der größeren Verantwortung der Klasse.

Mike Partridge
quelle