Aus der SOLID Prinzipien Perspektive Antwort jgauffin die Sinn macht. Vergessen Sie jedoch nicht die allgemeinen Gestaltungsprinzipien, z . B. das Ausblenden von Informationen .
Ich sehe mehrere Probleme mit dem angegebenen Ansatz:
- Wie Sie selbst bemerkt haben, erwarten die Leute nicht, das Schlüsselwort 'new' zu verwenden, wenn das erstellte Objekt keinen Status verwaltet . Ihr Design spiegelt seine Absicht wider. Benutzer Ihrer Klasse können sich nicht sicher sein, welchen Status sie verwaltet und ob nachfolgende Aufrufe der Methode zu einem anderen Verhalten führen können.
- Aus der Perspektive der Person, die die Klasse benutzt, ist der innere Zustand gut verborgen, aber wenn Sie Änderungen an der Klasse vornehmen oder sie einfach verstehen wollen, machen Sie die Dinge komplexer. Ich habe bereits viel über die Probleme geschrieben, die ich mit Aufteilungsmethoden sehe, um sie zu verkleinern , insbesondere, wenn der Status in den Klassenbereich verschoben wird. Sie ändern die Art und Weise, wie Ihre API verwendet werden soll, um kleinere Funktionen zu haben! Das geht meiner Meinung nach definitiv zu weit.
Einige verwandte Referenzen
Möglicherweise liegt ein Hauptargument darin, wie weit das Prinzip der einheitlichen Verantwortung gedehnt werden kann . "Wenn Sie es so extrem nehmen und Klassen bauen, die einen Grund haben zu existieren, haben Sie möglicherweise nur eine Methode pro Klasse. Dies würde eine große Zahl von Klassen verursachen, selbst für die einfachsten Prozesse, was dazu führen würde, dass das System existiert schwer zu verstehen und schwer zu ändern. "
Ein weiterer relevanter Verweis zu diesem Thema: "Unterteilen Sie Ihre Programme in Methoden, die eine identifizierbare Aufgabe ausführen. Halten Sie alle Operationen in einer Methode auf derselben Abstraktionsebene ." - Kent Beck Key ist hier "dieselbe Abstraktionsebene". Das bedeutet nicht "eins", wie es oft interpretiert wird. Diese Abstraktionsebene hängt vollständig von dem Kontext ab, für den Sie entwerfen.
Was ist der richtige Ansatz?
Ohne Ihren konkreten Anwendungsfall zu kennen, ist es schwer zu sagen. Es gibt ein Szenario, in dem ich manchmal (nicht oft) einen ähnlichen Ansatz verwende. Wenn ich einen Datensatz verarbeiten möchte, ohne diese Funktionalität für den gesamten Klassenbereich verfügbar machen zu wollen. Ich habe einen Blog-Beitrag darüber geschrieben, wie Lambdas die Kapselung noch weiter verbessern können . Ich habe auch eine Frage zum Thema hier auf Programmierer gestartet . Das Folgende ist ein aktuelles Beispiel für die Verwendung dieser Technik.
new TupleList<Key, int>
{
{ Key.NumPad1, 1 },
...
{ Key.NumPad3, 16 },
{ Key.NumPad4, 17 },
}
.ForEach( t =>
{
var trigger = new IC.Trigger.EventTrigger(
new KeyInputCondition( t.Item1, KeyInputCondition.KeyState.Down ) );
trigger.ConditionsMet += () => AddMarker( t.Item2 );
_inputController.AddTrigger( trigger );
} );
Da der örtliche Code im ForEach
nirgendwo anders wiederverwendet wird, kann ich ihn einfach genau dort aufbewahren, wo er relevant ist. Code so zu skizzieren, dass aufeinander aufbauender Code stark gruppiert ist, macht ihn meiner Meinung nach besser lesbar.
Mögliche Alternativen
- In C # könnten Sie stattdessen Erweiterungsmethoden verwenden. Arbeiten Sie also direkt mit dem Argument, das Sie an diese 'one thing'-Methode übergeben.
- Prüfen Sie, ob diese Funktion tatsächlich zu keiner anderen Klasse gehört.
- Machen Sie es zu einer statischen Funktion in einer statischen Klasse . Dies ist wahrscheinlich der am besten geeignete Ansatz, der sich auch in den allgemeinen APIs widerspiegelt, auf die Sie verwiesen haben.
bool arrayContainsSomestring = new List<string>(stringArray).Contains("somestring");
bei denen es mir nur darum ging, dass bestimmte Informationen und die LINQ-Erweiterungsmethoden nicht verfügbar sind. Funktioniert einwandfrei und passt in eineif()
Situation, in der Sie nicht durch Reifen springen müssen. Natürlich möchten Sie eine müllsammelnde Sprache, wenn Sie Code wie diesen schreiben.