Das Prinzip der Einzelverantwortung
("Jede Klasse sollte nur eine einzige Verantwortung haben. Mit anderen Worten, jede Klasse sollte einen und nur einen Grund haben, sich zu ändern.")
Ich stimme dir nicht zu. Ich denke, eine Methode sollte nur einen Grund haben, sich zu ändern, und alle Methoden in einer Klasse sollten eine logische Beziehung zueinander haben , aber die Klasse selbst könnte tatsächlich mehrere (verwandte) Dinge tun .
Nach meiner Erfahrung wird dieses Prinzip zu oft zu eifrig angewendet, und Sie haben am Ende viele winzige Ein-Methoden-Klassen. Beide agilen Shops, in denen ich gearbeitet habe, haben dies getan.
Stellen Sie sich vor, die Ersteller der .Net-API hätten diese Art von Mentalität: Anstelle von List.Sort (), List.Reverse (), List.Find () usw. hätten wir die Klassen ListSorter, ListReverser und ListSearcher!
Anstatt weiter gegen die SRP zu argumentieren (was theoretisch nicht schrecklich ist) , möchte ich einige meiner langwierigen anekdotischen Erfahrungen mitteilen:
An einer Stelle, an der ich gearbeitet habe, habe ich einen sehr einfachen Max-Flow-Löser geschrieben, der aus fünf Klassen bestand: einem Knoten, einem Diagramm, einem Diagrammersteller, einem Diagrammlöser und einer Klasse, um mit dem Diagrammersteller / -löser a zu lösen reales Problem. Keiner war besonders komplex oder lang (der Löser war mit ~ 150 Zeilen bei weitem der längste). Es wurde jedoch entschieden, dass die Klassen zu viele "Verantwortlichkeiten" hatten, also begannen meine Mitarbeiter mit der Umgestaltung des Codes. Als sie fertig waren, waren meine 5 Klassen auf 25 Klassen erweitert worden, deren gesamte Codezeilen mehr als das Dreifache dessen waren, was sie ursprünglich waren. Der Ablauf des Codes war nicht mehr offensichtlich, noch war der Zweck der neuen Unit-Tests; Es fiel mir jetzt schwer, herauszufinden, was mein eigener Code tat.
Am selben Ort hatte fast jede Klasse nur eine einzige Methode (ihre einzige "Verantwortung"). Es war fast unmöglich, dem Ablauf innerhalb des Programms zu folgen, und die meisten Unit-Tests bestanden darin, zu testen, ob diese Klasse Code aus einer anderen Klasse nannte , deren Zweck für mich gleichermaßen ein Rätsel war. Es gab buchstäblich Hunderte von Klassen, in denen es (IMO) nur Dutzende geben sollte. Jede Klasse hat nur eine "Sache" gemacht , aber selbst mit Namenskonventionen wie "AdminUserCreationAttemptorFactory" war es schwierig, die Beziehung zwischen Klassen zu bestimmen .
An einem anderen Ort (der auch die Mentalität hatte, nur eine Methode zu haben ) versuchten wir, eine Methode zu optimieren, die während einer bestimmten Operation 95% der Zeit in Anspruch nahm. Nachdem ich es (ziemlich dumm) ein wenig optimiert hatte, wandte ich mich der Frage zu, warum es eine Bajillion Mal genannt wurde. Es wurde in einer Schleife in einer Klasse aufgerufen ... deren Methode in einer Schleife in einer anderen Klasse aufgerufen wurde .. die auch in einer Schleife aufgerufen wurde ..
Insgesamt gab es fünf Ebenen von Schleifen, die (im Ernst) auf 13 Klassen verteilt waren. Es war unmöglich festzustellen, was eine Klasse tatsächlich tat, wenn man sie sich nur ansah - man musste ein mentales Diagramm darüber erstellen, welche Methoden sie nannte und welche Methoden diese Methoden nannten und so weiter. Wenn alles in eine Methode zusammengefasst worden wäre, wären es nur etwa 70 Zeilen gewesen, wenn unsere Problemmethode in fünf unmittelbar offensichtlichen Schleifenebenen verschachtelt gewesen wäre.
Meine Bitte, diese 13 Klassen in eine Klasse umzugestalten, wurde abgelehnt.