Nehmen wir an, Sie schreiben Ihr eigenes Logger-Dienstprogramm, und weil es einfach beginnt (ein Singleton mit Methoden, die auf stdout schreiben), entscheiden Sie sich, all seine Funktionalität in eine Klasse einzuordnen.Wie Sie das Sie denken mehr Funktionen verwenden, um es hinzuzufügen:
Sie, um verschiedene Dinge protokollieren können, wollen (auf stderr in eine Datei, in eine Warteschlange, was auch immer)
Sie wollen in der Lage sein, die Formatierung für Nachrichten zu ändern
Sie wollen getrennte Logger für verschiedene Kategorien
Sie Nachrichten zu filtern, für eine Kategorie von Protokollebene in der Lage sein
Sie wollen in der Lage Protokolliergrade on the fly
fügen Sie neue Protokollebenen (ERROR, WARN, INFO, DEBUG, usw.)
usw. zu ändern, und Sie hinzufügen die Implementierung für jede Funktion derselben Klasse, mit der Sie begonnen haben. Jede Änderung, die Sie vornehmen, bedeutet, in die gleiche Klasse zurückzukehren, sie zu sortieren, um zu sehen, was relevant ist, und dann Ihre Änderungen vorzunehmen. Da der gesamte Code in einer Klasse zusammengepackt ist und Methoden Code enthalten, der verschiedene Funktionen implementiert, kann es schwierig sein, alle relevanten Teile für Ihre Änderung aufzuspüren, und es besteht immer die Möglichkeit, dass sich eine Änderung unbeabsichtigt auf eine andere Funktion auswirkt dass einige bereits vorhandene Features unter bestimmten Umständen nicht mehr funktionieren. Sie müssen also alle Features in der Klasse und noch schlimmer alle Kombinationen aller Features testen, um diese Fehler zu erkennen. Das bedeutet, dass der Test unvollständig ist und sich Fehler einschleichen können.
Schauen Sie sich jetzt an, wie ein echtes Projekt wie log4j mit diesem Zeug umgeht. Es gibt eine Trennung von Belangen, bei der verschiedene Klassen die Formatierung handhaben, die Ausgabe der Ausgabe übergeben, einen Logger für eine Kategorie bereitstellen und die Interaktion zwischen all diesen Teilen klar definiert ist, mit dem Ergebnis, dass wenn man an einem Teil bastelt oder ersetzt betrifft nicht die anderen Stücke. Benutzer können ihre eigenen Klassen erstellen, die Funktionen hinzufügen, die sie benötigen (wo sie nicht alles über das Logframework wissen müssen, sie müssen nur den Vertrag für die bestimmte Art von Stück kennen, die sie hinzufügen wollen) und sie einstecken und Benutzer können verschiedene Plugins mischen und anpassen. Wenn ein Plugin kaputt ist, erstreckt sich dieser Bruch nicht über dieses Plugin hinaus und Änderungen an einzelnen Teilen gefährden nicht die Integrität des gesamten Projekts. In dem Maße, in dem Verträge die Interaktion der Teile regeln, müssen Sie nicht alle verschiedenen Kombinationen bestimmter Merkmale testen.
Mit dem Single-Class-Ansatz könnten Sie das nie tun, jedes bisschen neue Funktionalität, die jemand hinzugefügt hat, wäre eine Abzweigung des Projekts. Der Grundsatz des Single-Responsibility-Prinzips und der anderen SOLID-Regeln besteht darin, eine Gesamtstrategie zu bieten, die es ermöglicht, Software auf kontrollierte Weise zu ändern, ohne die Dinge zu stören.
Die einzige Möglichkeit, wirklich zu lernen, wäre, an einem realen Projekt zu arbeiten und Gegenbeispiele zu sehen, sogenannte God-Objects - Objekte, die Code haben, der sich mit zu vielen separaten Anliegen der Programmlogik befasst. Bei einem kleinen Projekt ist dieses Prinzip schwer zu visualisieren. –
http://www.objectmentor.com/resources/articles/srp.pdf –
[Satzzeichen] (http://en.wikipedia.org/wiki/Punctuation) ist dein Freund – keyser