2009-06-26 16 views
5

Okay, wir haben hier ein Dienstprogramm, das Geschäftsmodellklassen aus unseren Datenbanktabellen und -ansichten generiert, die einem ORM ähnlich sind (aber nicht ganz genau). Bei der Pflege ist mir aufgefallen, dass sich die Daten in den Schemata wahrscheinlich nicht sehr ändern werden. Die Funktionalität könnte jedoch. Wir möchten möglicherweise zusätzliche Funktionalität auf dem Weg hinzufügen. Wir möchten vielleicht etwas von dieser Funktionalität generieren, und wir möchten sie möglicherweise erweitern..NET Teilklassen vs. Vererbung

Die Klassen, die wir erstellen, befinden sich in einer Klassenbibliothek für die Verwendung durch andere Bibliotheken und Anwendungen. Keine große Überraschung dort. Aber der Stumper ist hier, wie generierte Klassen so entworfen werden, dass wir so wenig Code wie möglich zerstören, wenn wir eine Klasse neu generieren. Wenn beispielsweise Code zu einer Eigenschaft hinzugefügt wurde (die eine Spalte in einer Datenbanktabelle darstellt), möchten wir diese nicht verlieren.

So gibt es zwei Ansätze, die den Sinn springen:

Klassisches Erbe, wo die ganze Sache in einer einzigen „monolithischen“ Klasse gemacht wird und die Verbraucher sind frei, die Basisimplementierung außer Kraft zu setzen. Dies wird jedoch von Zeit zu Zeit etwas schwierig und wirft häufig Casting-Kopfschmerzen auf. Wenn die abgeleitete Klasse nicht vorsichtig ist und vergisst, Basisklassenfunktionen aufzurufen, können die Dinge schnell schiefgehen.

Teilklassen. In diesem Schema trennen wir das Geschäftsobjekt in verschiedene Teile: die Eigenschaften (die den Spalten zugeordnet werden) und die Verhaltensweisen. Verhaltensweisen könnten sogar weiter in generierte Verhaltensweisen und benutzerdefinierte Verhaltensweisen unterteilt werden. Das Problem mit diesem Ansatz ist, wie Sie sehen können, seine inhärente Komplexität. Außerdem gibt es das Problem der Namensgebung.

Hier ist meine Frage für Sie Leute: Wenn Sie mit einem solchen Szenario (wenn Sie jemals haben), oder wenn Sie mit einem solchen Szenario vorgestellt wurden, welche Lösungen würden Sie in Betracht ziehen, und warum?

+1

Nur um das Benennungsproblem zu kommentieren - meine Erfahrung mit Codegenerierungswerkzeugen ist, dass sie normalerweise nur eine große Datei mit all Ihren Klassen darin erzeugen. Auf diese Weise können Sie Ihren benutzerdefinierten Code einfach in Klassendateien einfügen, die nach Ihrer Klasse benannt sind. Normalerweise kommentieren wir die Kopfzeile, um deutlicher zu machen, dass an anderer Stelle generierter Code vorhanden ist. – womp

+0

Ich stimme diesem Ansatz nicht zu. Langfristige Entwickler pflegen Code in zwei verschiedenen Dateien und kurzfristige Entwickler unterliegen Änderungen außerhalb ihrer Kontrolle (Wenn Sie die Wiederherstellung auf einen bestimmten Zeitplan beschränken, wäre hilfreich). Viel Glück. – eschneider

Antwort

11

Der ganze Grund, warum Partial Classes in .Net enthalten sind, soll die Verwendung von Codegenerierungswerkzeugen erleichtern.

Wenn Sie Code generieren, verwenden Sie Teilklassen. Es ist wirklich so einfach. Warum würden Sie das Risiko eingehen, dass der Code im Lauf der Zeit neu generiert werden muss und Sie eine Menge Arbeit aufwenden müssten, um ihn mit Anpassungen neu zu aktualisieren?

Ich finde nicht, dass es auch bei Partials viel Komplexität gibt - es ist einfach eine Klasse, die auf mehrere Dateien aufgeteilt ist. Generierter Code in einer Datei, benutzerdefinierter Code in der anderen.

2

Ich würde Teil Klassen Pfad gehen. Nur weil es natürlicher ist, ein Objekt in viele Teile zu teilen. Sogar Linq2Sql verwendet Teiltöne. Kämpfe mit Komplexität mit Mustern und richtigen Konventionen. Und es ist einfacher, eine partielle Aktualisierung (wenn der generierte Code gut strukturiert ist) für partielle Klassen durchzuführen.

Wenn Sie keinen Code generieren - gehen Sie Klassenvererbung Weg (eigentlich würden Sie gezwungen sein, weil Partials nicht über verschiedene Assemblys hinweg funktionieren).

+0

"Mr. Downvoter", sei so nett und hinterlasse einen Grund. Ich würde mich freuen, etwas Neues zu lernen ... –

+0

Bitte lesen Sie die andere Antwort für Kommentare. – eschneider

+0

Danke, dass Sie darauf hingewiesen haben. –

2

Dies ist genau das Problem, dass partielle Klassen vorhanden sind, um zu lösen. Ich denke, dass Sie sie für praktische Zwecke vielleicht ein wenig zu weit abbrechen. Meine Bauchreaktion, ohne die feineren Details Ihrer Anwendung zu kennen, wäre die Verwendung einer partiellen Klassendatei für den gesamten generierten Code einer Klasse und einer zweiten Datei für den von Hand erstellten Code. Erstelle eine Namenskonvention für generierte Teilklassen und bleibe dabei.

+0

Ich würde das nie tun. Wenn Sie alle Teilklasse für alle DB-Änderungen neu erstellen, könnte oder wird wahrscheinlich die gesamte Codebasis beschädigt sein. Partials wurde hauptsächlich für die Designer hinzugefügt, und sind ein Hack für ein schlechtes Design IMO. – eschneider

+6

Ich stimme überhaupt nicht zu. Ich persönlich bin kein großer Fan von Codegenerierung, aber Teilklassen sind der einzige Weg, dies zu tun. Sie MÜSSEN einen Mechanismus haben, um den Code zu regenerieren, den Sie automatisch generieren möchten, ohne den Rest Ihres Klassencodes zu berühren. Teilklassen sind bei weitem die beste Lösung für dieses Problem. –

+2

Auch wenn es richtig gemacht wird, sollte keine Regeneration einer partiellen Klasse Ihre Codebasis brechen. Wegen der Magie der Kapselung. Sie können und sollten Ihren automatisch generierten Code an eine Schnittstelle anpassen, die von Ihren Klassen implementiert wird. Die wahrscheinlichsten Änderungen (Hinzufügen eines Feldes, Ändern eines Datentyps usw.) werden den Vertrag Ihrer Klasse nicht brechen. –

0

Wenn Sie einen Typ haben, der serialisiert werden soll (zu xml) und einige Funktionen hinzufügen möchten, müssen Sie partielle Klasse und nicht Vererbung verwenden. Dank /// M

0

Sie sagen:

ähnlich ist (aber nicht ganz genau wie) ein ORM

ich um die Wartungskosten für die aktuelle Lösung einige die Aussichten Zahlen ziehen würde (was ich vermute, ist signifikant) dann wählen Sie ein ORM, schreiben Sie eine Proof of Concept-Lösung und erstellen Sie Vergleichszahlen, um das zu erhalten. Ich bin mir nicht sicher, was dieses kundenspezifische Paket in der Art der Wartung, des Hochfahrens und des Entwicklers Kauf in kostet, aber ich würde für ein "Gewohnheits" Produkt wie dieses überhaupt nicht gehen. Das Wissen ist nicht übertragbar, das Fehlerrisiko ist hoch (immer der Fall bei der Codegenerierung) und Sie sind an die Intrakavität der zugrunde liegenden Datenbank gebunden.

+2

Sie wissen, dass diese Frage aus dem Jahr 2009 stammt, oder? Jedenfalls habe ich mich für die Teilklassenstrecke entschieden und es hat wunderbar funktioniert. Das von uns entwickelte Tool war sehr gut dokumentiert, und wir hatten keine ernsthaften Probleme damit. (Weder ich, noch irgendwelche Entwickler, die nach mir kamen.) –