Coding guides: Wie teilen Sie Ihre großen Quelldateien auf?

7

Das Projekt, an dem ich gerade arbeite, hat gerade 4200 Zeilen in der Haupt-C # -Datei erreicht, was dazu führt, dass IntelliSense einige Sekunden (manchmal bis zu 6) benötigt, um zu reagieren, währenddessen Visual Studio sich stürzt. Ich frage mich, wie alle anderen ihre Dateien aufteilen und ob es einen Konsens gibt.

Ich habe versucht, nach einigen Leitfäden zu suchen und Google C ++ Guide gefunden, aber ich konnte nicht Ich sehe nichts über Semantiken wie Funktionsgrößen und Dateigrößen; vielleicht ist es da - ich habe es eine Weile nicht angeschaut.

Wie teilen Sie Ihre Dateien auf? Gruppieren Sie Ihre Methoden nach den Funktionen, denen sie dienen? Nach Typen (Ereignishandler, privat / öffentlich)? Und bei welcher Größenbeschränkung teilen Sie Funktionen?

Um es klarzustellen: Die fragliche Anwendung handhabt Daten - also ist ihre Schnittstelle ein großes Raster, und alles dreht sich um das Raster. Es hat ein paar Dialoge Formulare für die Verwaltung, aber es geht nur um die Daten. Der Grund, warum es so groß ist, ist, dass es eine Menge Fehlerprüfung, Ereignisbehandlung und auch das Raster als Master-Detail mit drei weiteren Gittern für jede Zeile (aber diese laden auf Master-Zeile erweitert) gibt. Ich hoffe, das hilft mir zu erklären, worum es geht.

    
Nick Devereaux 03.03.2009, 22:38
quelle

14 Antworten

19

Ich denke, Ihr Problem ist mit dem Begriff zusammengefasst, den Sie verwenden: "Haupt-C # -Datei".

Wenn Sie nicht main (wie in der Methode main ()) meinen, gibt es keinen Platz für dieses Konzept.

Wenn Sie eine Catch-All-Dienstprogrammklasse oder andere gebräuchliche Methoden haben, sollten Sie sie in ähnliche Funktionsteile aufteilen.

Normalerweise sind meine Dateien nur Eins-zu-eins-Zuordnungen von Klassen.

Manchmal befinden sich sehr ähnliche Klassen in derselben Datei.

Wenn Ihre Datei zu groß ist, ist Ihre Klasse zu groß und zu allgemein.

Ich versuche, meine Methoden auf einem halben Bildschirm oder weniger zu halten. (Wenn es Code ist, schreibe ich von Grund auf neu, es sind normalerweise 12 Zeilen oder weniger, aber in letzter Zeit habe ich in existierendem Code von anderen Entwicklern gearbeitet und muss 100 Zeilenfunktionen umgestalten ...)

Manchmal ist es ein Bildschirm, aber das wird sehr groß.

BEARBEITEN:

Um Ihre Größenbeschränkungsfrage nach Funktionen zu beantworten - für mich geht es weniger um die Größe (obwohl dies ein guter Indikator für ein Problem ist) und mehr darum, nur eine Sache zu machen und jede EINFACH zu halten.

    
Tim 03.03.2009, 22:42
quelle
15

Im klassischen Buch " Strukturierte Programmierung " schrieb Dijkstra einmal einen Abschnitt mit dem Titel: "Über unsere Unfähigkeit zu tun viel." Sein Standpunkt war einfach. Menschen sind nicht sehr schlau. Wir können nicht mehr als ein paar Konzepte gleichzeitig in unseren Köpfen jonglieren.

Es ist sehr wichtig, dass Ihre Klassen und Methoden klein bleiben. Wenn eine Methode mehr als ein Dutzend Zeilen erreicht, sollte sie auseinander gebrochen werden. Wenn eine Klasse über ein paar hundert Zeilen kommt, sollte sie auseinander gebrochen werden. Nur so kann der Code gut organisiert und verwaltet werden. Ich programmiere seit fast 40 Jahren, und mit jedem Jahr, das vergangen ist, merke ich, wie wichtig das Wort "klein" beim Schreiben von Software ist.

Was wie Sie tun dies, dies ist ein sehr großes Thema, das über viele verschiedene Zeiten geschrieben wurde. Es dreht sich alles um Abhängigkeitsverwaltung, Informationsverbergung und objektorientiertes Design im Allgemeinen. Hier ist eine Leseliste.

Uncle Bob 07.03.2009 17:29
quelle
14

Teilen Sie Ihre Typen auf, wo es normal ist, sie zu teilen - aber passen Sie auf Typen auf, die zu viel tun. Bei ungefähr 500 Zeilen (von Java oder C #) werde ich besorgt. Bei etwa 1000 Zeilen fange ich an, genau hinzuschauen, ob der Typ aufgeteilt werden soll ... aber manchmal kann / sollte es nicht sein.

Was Methoden anbelangt: Ich mag es nicht, wenn ich die ganze Methode nicht gleichzeitig auf dem Bildschirm sehen kann. Offensichtlich hängt das von der Größe des Monitors usw. ab, aber es ist eine vernünftige Faustregel. Ich bevorzuge es jedoch, dass sie kürzer sind. Auch hier gibt es Ausnahmen - einige Logik ist wirklich schwer zu entwirren, besonders wenn es viele lokale Variablen gibt, die natürlich nicht zusammen gekapselt werden wollen.

Manchmal macht es Sinn, wenn ein einzelner Typ eine Menge von Methoden hat - wie zB System.Linq.Enumerable aber partielle Klassen können in solchen Fällen helfen, wenn Sie die Art bis in logische Gruppen (im Fall Enumerable brechen können, durch Aggregation Gruppierung / set Operationen / Filterung usw. würde natürlich scheinen). Solche Fälle sind in meiner Erfahrung jedoch selten.

    
Jon Skeet 03.03.2009 22:41
quelle
5

Martin Fowlers Buch Refactoring Ich denke, Sie haben einen guten Ausgangspunkt dafür. Es weist darauf hin, wie man "Code Smells" identifiziert und wie man seinen Code umgestaltet, um diese "Gerüche" zu beheben. Das natürliche Ergebnis (obwohl es nicht das primäre Ziel ist) ist, dass Sie mit kleineren, besser wartbaren Klassen enden.

BEARBEITEN

Angesichts Ihrer Bearbeitung habe ich immer darauf bestanden, dass die Code-Programmierung für Back-End-Code in der Präsentationsschicht gleich ist. Einige sehr nützliche Muster, die für UI-Refactorings berücksichtigt werden müssen, sind Befehl, Strategie, Spezifikation und Status.

Kurz gesagt, Ihre Ansicht sollte nur Code enthalten, um Ereignisse zu verarbeiten und Werte zuzuweisen. Alle Logik sollte in eine andere Klasse getrennt werden. Sobald Sie dies tun, werden Sie feststellen, dass es deutlicher wird, wo Sie umgestalten können. Grids machen dies ein wenig schwieriger, weil sie es zu einfach machen, Ihren Präsentationszustand zwischen der Präsentationslogik und der Ansicht aufzuteilen, aber mit etwas Arbeit können Sie Indirektion einsetzen, um den dadurch verursachten Schmerz zu minimieren .

    
Michael Meadows 03.03.2009 22:50
quelle
4

Verarbeiten Sie nicht prozedural, und Sie werden nicht mit 4.200 Zeilen in einer Datei enden.

In C # ist es eine gute Idee, sich an einige objektorientierte Designprinzipien der SOLID -Ansicht zu halten. Jede Klasse sollte einen einzigen Grund haben, sich zu ändern. Die Hauptmethode sollte einfach den Startpunkt für die Anwendung starten (und den Dependency-Injektionscontainer konfigurieren, wenn Sie etwas wie StructureMap verwenden).

Ich habe generell keine Dateien mit mehr als 200 Zeilen Code, und ich bevorzuge sie, wenn sie unter 100 sind.

    
Chris Holmes 03.03.2009 22:44
quelle
3

Es gibt keine festen Regeln, aber es gibt eine allgemeine Übereinstimmung, dass mehr, kürzere Funktionen besser sind als eine einzige große Funktion, und kleinere Klassen besser als eine große Klasse.

Bei Funktionen, die größer als 40 Zeilen sind, sollten Sie überlegen, wie Sie diese aufteilen können. Sehen Sie sich insbesondere Nested Loops an, die verwirrend und oft einfach zu Funktionsaufrufen mit netten beschreibenden Namen zu übersetzen sind.

Ich zerlege Klassen, wenn ich glaube, dass sie mehr als eine Sache machen, wie Mix-Präsentation und Logik. Eine große Klasse ist weniger ein Problem als eine große, solange die Klasse eine Sache macht.

Der Konsens in den Styleguides, den ich gesehen habe, besteht darin, Methoden nach Zugriff zu gruppieren, wobei Konstruktoren und öffentliche Methoden oben stehen. Alles, was konsistent ist, ist großartig.

Sie sollten sich über C # -Stil und Refactoring informieren, um die von Ihnen angesprochenen Probleme wirklich zu verstehen.

Refactoring ist ein hervorragendes Buch, das Tipps zum Umschreiben von Code enthält, damit das Verhalten erhalten bleibt, aber der Code klarer und einfacher zu handhaben ist.

Elemente von C # -Stil ist eine gute tote Baum C # style guide, und dies Blogpost enthält eine Reihe von Links zu guten Online-Style-Guides.

Schließlich sollten Sie FxCop und StyleCop . Diese helfen nicht bei den von Ihnen gestellten Fragen, können jedoch andere stilistische Probleme mit Ihrem Code erkennen. Da du deinen Zeh ins Wasser getaucht hast, kannst du auch hineinspringen.

Das ist viel, aber die Entwicklung von Geschmack, Stil und Klarheit ist ein großer Unterschied zwischen guten und schlechten Entwicklern.

    
RossFabricant 03.03.2009 22:57
quelle
2

Jede Klasse sollte eine kleine Sache machen und es gut machen. Ist deine Klasse ein Formular? Dann sollte es keine Geschäftslogik darin haben.

Stellt es ein einzelnes Konzept dar, wie einen Benutzer oder einen Staat? Dann sollte es keine Zeichnung haben, laden / speichern, etc ...

Jeder Programmierer durchläuft Stufen und Ebenen. Du erkennst ein Problem mit deinem aktuellen Level und du bist bereit, dich dem nächsten zu nähern.

Nach dem, was Sie gesagt haben, klingt es so, als wäre Ihr derzeitiges Level "Ein Problem lösen", höchstwahrscheinlich mit prozeduralem Code, und Sie müssen beginnen, sich mehr neue Wege zu nähern, um sich diesem zu nähern.

Ich empfehle, zu überlegen, wie man wirklich OO-Design macht. Es gibt viele Theorien, die Sie wahrscheinlich gehört haben, die keinen Sinn ergeben. Der Grund dafür ist, dass sie nicht auf die Art und Weise, wie Sie gerade programmieren, zutreffen.

Lemme einen guten Beitrag finden ... Schau dir diese an, um zu beginnen:

how-do-i-break-my-Prozedurcodierung - Bewohner

sind-es-gibt-Regeln-für-oop

objektorientiert-best-practices-vererbung-v -composition-v-interfaces

Es gibt auch Artikel, die dich auf gute OO-Designbücher verweisen. Ein "Refactoring" -Buch ist wahrscheinlich einer der besten Orte, an denen man anfangen kann.

Sie sind gerade in einem guten Punkt, aber Sie würden nicht glauben, wie weit Sie gehen müssen. Ich hoffe, Sie sind begeistert, denn einige dieser Dinge in Ihrer nahen Zukunft sind einige der besten "Lernerfahrungen", die Sie jemals haben werden.

Viel Glück.

    
Bill K 03.03.2009 23:25
quelle
1

Sie können nach kleinen Dingen suchen, die Sie im Laufe der Zeit verändern und verändern können.

  • Werden alle Methoden nur in dieser Klasse verwendet? Suchen Sie nach Unterstützungsmethoden wie Validierung, String-Manipulation, die in helper / util-Klassen verschoben werden kann.

  • Benutzt du irgendwelche #region Abschnitte? Logische Gruppierungen verwandter Methoden in einer # Region bieten sich oft an, in separate Klassen aufgeteilt zu werden.

  • Ist die Klasse ein Formular? Erwägen Sie, Benutzersteuerelemente für Formularsteuerelemente oder Gruppen von Formularsteuerelementen zu verwenden.

Manchmal entwickeln sich große Klassen im Laufe der Zeit aufgrund der vielen Entwickler, die schnelle Verbesserungen / neue Funktionen vornehmen, ohne das Gesamtdesign zu berücksichtigen. Überdenken Sie einige der Links zur Designtheorie, die andere hier zur Verfügung gestellt haben, und ziehen Sie eine fortlaufende Unterstützung in Betracht, um diese durchzusetzen, z. B. Code-Reviews und Teamworkshops zur Überprüfung des Designs.

    
Leah 04.03.2009 01:07
quelle
1

Nun, ich habe Angst zu sagen, dass Sie ein größeres Problem zur Hand haben als eine langsame Ladezeit. Sie werden Probleme mit eng gekoppelten Code- und Wartbarkeits- / Lesbarkeitsproblemen haben.

Es gibt sehr gute Gründe, Klassendateien in kleinere Dateien aufzuteilen (und ebenso gute Gründe, Dateien in andere Projekte / Assemblies zu verschieben).

Denken Sie darüber nach, welchen Zweck Ihre Klasse erfüllen soll. Jede Datei sollte eigentlich nur einen Zweck haben. Wenn es in seinem Ziel zu verallgemeinert ist, zum Beispiel "Shopping Basket Logic", dann sind Sie auf dem falschen Weg.

Wie bereits erwähnt, riecht der Begriff, den Sie verwenden: "Haupt-C # -Datei" nur, dass Sie eine sehr prozedurale Denkweise haben. Mein Rat wäre, aufzuhören, einen Schritt zurückzutreten und sich einige der folgenden Themen kurz durchzulesen:

  • Allgemeine OOP-Prinzipien
  • Domain-driven Design
  • Komponententest
  • IoC Container

Viel Glück bei Ihren Suchen.

    
Owen 03.03.2009 22:48
quelle
0

Vielleicht kann das OP antworten: Ist Ihr Projekt objektorientierte Programmierung? Die Tatsache, dass Sie das Wort "Datei" verwenden, deutet darauf hin, dass dies nicht der Fall ist.

Bis Sie die Objektorientierung verstehen, gibt es keine Hoffnung, Ihren Code in irgendeiner wichtigen Weise zu verbessern. Du solltest besser die Datei überhaupt nicht aufteilen, warten, bis sie unerträglich langsam und fehlerhaft wird, und dann, anstatt sie zu tragen, OO lernen.

    
John Saunders 04.03.2009 02:46
quelle
0

Der Intellisense-Parser in Visual Studio 2008 scheint wesentlich schneller zu sein als der 2005 (ich weiß, dass sie in diesem Bereich besonders viel Arbeit gemacht haben), also sollten Sie auf jeden Fall die Datei aufspalten wie andere Haben Sie erwähnt, Visual Studio 2008 kann Ihr sofortiges Leistungsproblem beheben. Ich habe es verwendet, um eine 100K + -Zeile Linq zu SQL-Datei ohne viel Problem zu öffnen.

    
tbreffni 04.03.2009 02:55
quelle
0

Teilen Sie den Code so auf, dass jede Klasse / Datei / Funktion / etc. macht nur One Thing ™. Das Prinzip der einheitlichen Verantwortung ist eine gute Richtlinie, um Funktionalität in Klassen aufzuteilen.

Heutzutage sind die größten Klassen, die ich schreibe, etwa 200 Zeilen lang, und die Methoden sind meistens 1-10 Zeilen lang.

    
Esko Luontola 07.03.2009 18:07
quelle
0

Wenn Sie Codebereiche in einer Klasse haben, besteht eine einfache Methode darin, das Schlüsselwort partial zu verwenden und die Definition der Klasse in diese Datei aufzuteilen. Ich mache das normalerweise für große Klassen.

Die Konvention, die ich verwende, ist ClassName_RegionName.cs. Wenn ich zum Beispiel eine Klasse erstellen möchte, die das Schema für eine Datenbankverbindung verwaltet, und ich die Klasse DatabaseConnection aufgerufen habe, würde ich eine Datei namens DatabaseConnection.cs für die Hauptklasse und dann DatabaseConnection_Schema.cs für die Schemafunktionalität erstellen / p>

Manche Klassen müssen einfach groß sein. Das ist kein schlechtes Design; Sie sind nur umsetzungsstark.

    
Jeremy Edwards 03.03.2009 23:23
quelle
-1

Verwenden Sie Teilklassen. Sie können grundsätzlich eine einzelne Klasse in mehrere Dateien aufteilen.

    
NotMe 03.03.2009 22:41
quelle