Ich finde es heutzutage nicht sinnvoll, darüber zu diskutieren, was eine einzige Verantwortung oder einen einzigen Grund für eine Änderung darstellt oder nicht. Ich würde an seiner Stelle ein Minimum-Trauer-Prinzip vorschlagen:
Prinzip der minimalen Trauer: Code sollte entweder versuchen, die Wahrscheinlichkeit zu minimieren, dass Änderungen erforderlich sind, oder den Änderungskomfort maximieren.
Wie ist das? Ein Raketenwissenschaftler sollte nicht herausfinden, warum dies zur Senkung der Wartungskosten beitragen kann, und hoffentlich sollte es kein endloser Streitpunkt sein, aber wie bei SOLID im Allgemeinen ist es nicht überall blind anzuwenden. Es ist etwas zu beachten, während Kompromisse ausgeglichen werden.
Die Wahrscheinlichkeit, dass Änderungen erforderlich sind, hängt mit folgenden Faktoren zusammen:
- Gute Prüfung (verbesserte Zuverlässigkeit).
- Bezieht sich nur auf das Nötigste, um etwas Bestimmtes zu tun (dies kann das Reduzieren afferenter Kopplungen einschließen).
- Machen Sie den Code einfach zu dem, was er tut (siehe Make Badass Principle).
Die Schwierigkeit, Änderungen vorzunehmen, geht mit efferenten Kupplungen einher. Das Testen führt zu efferenten Kupplungen, verbessert jedoch die Zuverlässigkeit. Gut gemacht, tut es im Allgemeinen mehr gut als schaden und ist absolut akzeptabel und wird durch das Minimum Grief-Prinzip gefördert.
Make Badass-Prinzip: Klassen, die an vielen Orten verwendet werden, sollten fantastisch sein. Sie sollten zuverlässig und effizient sein, wenn dies mit ihrer Qualität zusammenhängt usw.
Und das Make-Badass-Prinzip ist an das Minimum-Grief-Prinzip gebunden, da Badass-Dinge mit geringerer Wahrscheinlichkeit Änderungen erfordern als Dinge, die an dem scheißen, was sie tun.
Ich hätte zunächst auf das oben erwähnte Paradox hingewiesen und dann darauf hingewiesen, dass die SRP in hohem Maße von der zu berücksichtigenden Granularität abhängt und dass eine Klasse, die mehr als eine Eigenschaft oder eine Methode enthält, einen Verstoß darstellt, wenn Sie weit genug gehen es.
Aus SRP-Sicht hätte eine Klasse, die kaum etwas tut, sicherlich nur einen (manchmal null) Änderungsgrund:
class Float
{
public:
explicit Float(float val);
float get() const;
void set(float new_val);
};
Das hat praktisch keinen Grund, sich zu ändern! Es ist besser als SRP. Es ist ZRP!
Außer ich würde vorschlagen, dass es eine offensichtliche Verletzung des Make Badass Prinzips ist. Es ist auch absolut wertlos. Etwas, das so wenig bewirkt, kann nicht hoffentlich schlecht sein. Es hat zu wenig Informationen (TLI). Und natürlich, wenn Sie etwas haben, das TLI ist, kann es nichts wirklich Bedeutendes bewirken, auch nicht mit den darin enthaltenen Informationen, und es muss nach außen geleitet werden, in der Hoffnung, dass jemand anderes tatsächlich etwas Bedeutendes und Böses tut. Und diese Undichtigkeit ist in Ordnung für etwas, das nur dazu gedacht ist, Daten und nichts weiter zu aggregieren, aber diese Schwelle ist der Unterschied, den ich zwischen "Daten" und "Objekten" sehe.
Natürlich ist etwas, was TMI ist, auch schlecht. Wir könnten unsere gesamte Software in eine Klasse einteilen. Es kann sogar nur eine run
Methode geben. Und jemand könnte sogar argumentieren, dass es jetzt einen sehr allgemeinen Grund für eine Änderung gibt: "Diese Klasse muss nur geändert werden, wenn die Software verbessert werden muss." Ich bin dumm, aber natürlich können wir uns alle Wartungsprobleme damit vorstellen.
Es gibt also einen Spagat in Bezug auf die Granularität oder Grobheit der von Ihnen entworfenen Objekte. Ich beurteile es oft daran, wie viele Informationen Sie an die Außenwelt weitergeben müssen und wie viele sinnvolle Funktionen sie ausführen können. Ich finde das Make-Badass-Prinzip oft hilfreich, um das Gleichgewicht zu finden und es mit dem Minimum-Grief-Prinzip zu kombinieren.