Meine Klassen und Methoden so klein wie möglich halten?


20

Vor ein paar Tagen sprach ich mit einer Doktorandin der Softwaretechnik und irgendwann sagte sie zu mir:

Halten Sie Ihre Klassen und Methoden so klein wie möglich

Und ich frage mich, ob dies immer eine gute Praxis ist.

Ich meine, ist es zum Beispiel wert, eine Klasse mit nur 2 Attributen zu haben? Zum Beispiel brauche ich bei einigen Methoden Paare von ganzen Zahlen, um damit zu arbeiten. Soll ich eine "PairOfIntgers" -Klasse schreiben?

Könnte diese Denkweise den Code in zu viele Teile "brechen"?


10
Das sollte sein"As small as possible, but no smaller."
StuperUser

"Ich meine, ist es zum Beispiel wert, eine Klasse mit nur 2 Attributen zu haben?" - Es kann sein, nach "Primitive Obsession" zu suchen (zB jamesshore.com/Blog/PrimitiveObsession.html )
Torsten

Ich denke, die Quelle der Verwirrung ist das Wort "möglich". Das Prinzip wird lächerlich, wenn sich "möglich" nur auf den Code bezieht, weil die kleinstmögliche Klasse, die etwas Nützliches tut, nur eine Methode hat (und in einigen Fällen Null). Der Kandidat wollte sehr wahrscheinlich den Zusammenhalt und die Kopplung berücksichtigen.
Kelvin

Antworten:


23

In diesem Rat steckt ein Körnchen Wahrheit, aber meiner Meinung nach ist er nicht sehr gut ausgedrückt und daher leicht zu missverstehen und / oder auf ein dummes Extrem zu bringen. In jedem Fall sollte dies eher eine Faustregel als ein hartes Gesetz sein. Und Sie sollten in solchen Regeln immer die Klausel "innerhalb angemessener Grenzen" oder "aber vergessen Sie nicht, Ihren gesunden Menschenverstand zu verwenden" implizieren :-)

Das Korn der Wahrheit ist, dass in der Praxis Klassen und Methoden immer dazu neigen, von Natur aus zu wachsen, nicht zu schrumpfen . Ein Bugfix hier, eine kleine Funktionserweiterung dort, die einen Sonderfall dort behandelt ... und voila, Ihre einst ordentliche und kleine Klasse, fängt an aufzublähen. Im Laufe der Zeit wird Ihr Code fast unweigerlich zu einem ungeheuren Durcheinander von Spaghetti - es sei denn, Sie bekämpfen diese Tendenz aktiv durch Refactoring . Beim Refactoring entstehen fast immer viele kleinere Klassen / Methoden aus wenigen großen. Aber natürlich gibt es eine sinnvolle Grenze für die Miniaturisierung. Beim Refactoring geht es nicht darum, kleinere Klassen und Methoden an sich zu haben, sondern Ihren Code übersichtlicher, verständlicher und leichter zu pflegen. Ab einem bestimmten Punkt verringert sich die Lesbarkeit, wenn Sie Ihre Methoden / Klassen verkleinern, anstatt sie zu erhöhen. Streben Sie dieses Optimum an. Es ist ein verschwommenes und sich bewegendes Zielgebiet, sodass Sie es nicht genau treffen müssen. Verbessern Sie den Code einfach ein wenig, wenn Sie ein Problem damit feststellen .


1
definitiv eine regel, der man nicht blind folgen sollte, zu viele winzige klassen sind die meiste zeit so viel schlimmer als ein paar größere klassen.
Ryathal

4
Meine persönliche Faustregel lautet: Wenn Sie keine vollständige Methodenimplementierung auf dem Bildschirm sehen können, müssen Sie refactor.
Dan Ray

6
@ DanRay, ja, ich hatte die gleiche Regel, bis ich Clean Code las . Es war ein ziemlicher Schock, aber mein Optimum ging allmählich auf etwa 10 Zeilen zurück.
Péter Török

2
IMO Clean Code ist in seiner Extremität gegenüber kleinen Methoden schrecklich. Das Problem ist, dass es bei kleineren Methoden mehr davon gibt. Natürlich sind zu lange Methoden zu lang, aber Bob Martin scheint 10 1-Zeilen-Methoden einer 10-Zeilen-Methode vorzuziehen (daher nimmt derselbe Code ungefähr das Fünffache des Bildschirmplatzes in Anspruch). Vielleicht soll es eine Art pädagogischer Trick sein, ich kann nicht glauben, dass jemand den Code in diesem Buch wirklich für gut hält.
Joonas Pulakka

5
@JoonasPulakka - Sagen wir einfach, ich habe noch nie eine Methode gelesen und gedacht: "Ich wünschte, diese Methode würde mehr bewirken." Durch das Verkürzen von Methoden können Sie sehr beschreibende Methodennamen schreiben, die häufig das vollständige Lesen des Methodenkörpers überflüssig machen. Ich fand den Rat in Clean Code sehr vernünftig. Wir müssen nur zustimmen, dass wir nicht zustimmen. :)
David Harkness

9

Das wichtigere Thema, das hier betont werden muss, ist die Schaffung guter Abstraktionen . Kleine Klassen , die lose gekoppelt sind und eine hohe Kohäsion aufweisen, sind das Produkt guter Abstraktionen .

Manchmal ist es sinnvoll, zwei ganze Zahlen in einer Klasse zu kapseln. Insbesondere, wenn dieser Klasse Methoden zugeordnet werden sollen, um auch zu kapseln, wie diese Attribute bearbeitet werden können, und um sicherzustellen, dass Sie sie vor anderen Teilen des Programms schützen, die sie ändern.

Ein weiterer Vorteil beim Erstellen einer Klasse in diesem Fall ist, dass sich die Klasse viel besser / schöner entwickeln kann, als es eine Datenstruktur auf niedrigerer Ebene wie eine Karte oder eine Liste kann.

Drittens kann eine gute Abstraktion die Lesbarkeit erheblich verbessern. Klassen, die sich an SRP halten, sind für einen Menschen in der Regel viel einfacher zu verstehen als Klassen, die dies nicht tun.

Und als letzte Anmerkung ... egal wie gut Sie als Student sind ... um OOP und gute Abstraktionen zu verstehen und wann man sie einsetzt, brauchen Sie Erfahrung. Sie müssen schlechten Code schreiben und den Schmerz durchgehen, um ihn zu pflegen. Sie müssen sehen, wie andere guten Code schreiben, um Ihr Wissen darüber aufzubauen, was „gut“ ist und was auf der ganzen Linie ein Problem sein wird.


2

Das Gott-Objekt-Anti-Muster ist das, worauf sie wahrscheinlich anspielte. Ich neige dazu zu denken, dass wenn ich ein "und" in meiner Klassenbeschreibung habe, ich zwei Klassen haben sollte. Wenn eine Methode / Funktion mehr als zehn Codezeilen enthält, sollte ich sie auflösen. Als Piratencode sind dies mehr Richtlinien als Regeln.


2

In der objektorientierten Programmierung besagt das Prinzip der Einzelverantwortung, dass jedes Objekt eine Einzelverantwortung haben sollte und dass die Verantwortung vollständig von der Klasse eingekapselt werden sollte. Normalerweise tun Sie mehr als eine Sache, wenn Ihre Klasse zu groß wird. In Ihrem Fall ist die Klasse nur eine Datenklasse, die Daten enthält, die absolut in Ordnung sind. Sie sollten die Klasse PairOfInteger nicht benennen. Was beschreiben die ganzen Zahlen? Abhängig von Ihrem Szenario kann auch ein Tupel (wie in C #) ausreichend sein. Und vielleicht möchten Sie an eine Strebe statt an eine Klasse denken.

Versuchen Sie, Sie Klassen klein zu halten. Und Methoden noch kleiner. Vielleicht 10 Zeilen?!? Momentan versuche ich, Flow-Design und ereignisbasierte Komponenten zu verwenden, die dazu beitragen, Klassen klein zu halten. Zuerst habe ich mir Sorgen gemacht, dass ich in viele Klassen komme, aber es funktioniert wirklich !!! http://geekswithblogs.net/theArchitectsNapkin/archive/2011/03/19/flow-design-cheat-sheet-ndash-part-i-notation.aspx http://geekswithblogs.net/theArchitectsNapkin/archive/2011/03 /20/flow-design-cheat-sheet-ndash-part-ii-translation.aspx


2

Machen Sie die Dinge so einfach wie möglich, aber nicht einfacher. Das ist die Regel, nach der ich versuche zu handeln. Manchmal ist es tatsächlich sinnvoll, dass eine Klasse genau genommen mehr als eine Sache tut, wenn diese Dinge mit einem gemeinsamen Thema zusammenhängen . Sehen Sie sich .NET an. Es gibt Unmengen von Klassen, die eine große Anzahl von Schnittstellen implementieren, von denen jede eine eigene Liste der erforderlichen Mitglieder enthält. Eine Methode kann etwas langwierig werden, wenn sie komplexe Aufgaben mit einer Reihe von Zwischenschritten ausführt, die alle miteinander verbunden sind und sich daher nicht für eine weitere Umgestaltung eignen. (Refactoring, um die Methoden kurz zu halten, sollte sich letztendlich um Lesbarkeit und Wartbarkeit handeln. Wenn die lange Methode lesbarer und / oder wartbarer ist als eine kurze, alle anderen sind gleich, nehme ich die lange jeden Tag.)

Nur "Klassen und Methoden so klein wie möglich zu machen", ist meiner Meinung nach falsch. Die eigentliche Herausforderung besteht darin, wie @c_maker betont, gute Abstraktionen bereitzustellen. Ihr Beispiel für das Gruppieren von zwei Zahlen ist großartig, wenn Sie beispielsweise an einer Implementierung von Arithmetik mit komplexen Zahlen arbeiten oder wenn Sie auf einem Unix-System auf einen Benutzer- / Gruppenkontext verweisen müssen. Es ist sehr wenig sinnvoll, wenn die Zahlen beispielsweise eine Rechnungs-ID und eine Produkt-ID darstellen, die dieser Rechnung hinzugefügt werden sollen.


0

Das ist ein guter Rat, aber er muss einigermaßen intelligent umgesetzt werden. Folgen Sie ihm auf keinen Fall blind.

Wenn ich mir meinen Code ansehe, weiß ich, ob eine Methode zu groß ist. Wenn es zu viel macht und zu schwer zu lesen ist, dann ist Refactor-Zeit.

Hier ist ein gutes Beispiel: Sie haben eine Schleife und in dieser Methode möglicherweise 60 Codezeilen. In diesem Fall ist es wahrscheinlich Zeit für eine Umgestaltung, da Sie wahrscheinlich zu viel in dieser Methode tun.

Aber es ist keine feste Regel. Es ist nur etwas, was Sie lernen können, indem Sie es tun. Und andere Entwickler, mit denen Sie zusammenarbeiten, sind nicht immer einverstanden und rufen Sie möglicherweise zu einer Codeüberprüfung auf oder was auch immer.


Verkleinern Sie niemals die Methoden, sondern folgen Sie der SRP und sie erledigen die Arbeit automatisch.
Vinay Prajapati

0

Onkel Bob sagt, Sie sollten Ihre Methoden umgestalten, aufteilen und extrahieren, bis es unmöglich ist, sie kleiner zu machen . Dies führt normalerweise zu mehreren Methoden mit jeweils 3 oder 4 Zeilen. Wenn Sie zu viele Methoden erhalten, müssen Sie mehr Klassen erstellen.

Wenn Sie versuchen, SRP und einer Abstraktionsebene pro Methode zu folgen, sind diese Regeln hilfreich. Zumindest dienen sie mir gut. Das Streben nach "so klein wie möglich" gibt mir vernünftige kleine Methoden, da ich normalerweise das Ziel verfehle.

Und es ist immer einfacher, kleinere Klassen zu verstehen. Lesen Sie "Clean Code"

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.