Ich mache Branchen-Apps, bei denen alle anderen Entwickler an grundlegende CRUD-Apps gewöhnt sind oder sich ausschließlich darauf konzentrieren, hübsche / funktionale Schnittstellen zu erstellen, und ich bekomme viel Folgendes.
"Mit der Art und Weise, wie wir es machen, hätte der Mitarbeiter alles, was man mit einem Mitarbeiter machen könnte." Und es war wahr. Diese eine "Klasse" hatte Tausende von Codezeilen und alles, was man mit einem Mitarbeiter machen konnte, war da. Oder, noch schlimmer, es gab eine Tabelle mit Mitarbeiterdaten, und jeder Entwickler fand heraus, wie er das tun sollte, was er im Event-Handler tun wollte.
All die schlechten Dinge an diesem Ansatz waren wahr, aber zumindest der Entwickler, der einen Mitarbeiter verwendet, konnte, ohne zu anderen Dokumenten zu gehen, herausfinden, wie er den Mitarbeiter in einen Gesundheitsplan einschreiben, eine Gehaltserhöhung vornehmen, entlassen, einstellen, transferieren usw. Gleiches gilt für Manager und alle anderen wichtigen Ideen. Oder wenn sie dem Mitarbeiter andere benötigte Datentabellen verwenden, können sie einfach tun, was sie wollen.
Ja, es gab viel doppelten Code. Ja, es war sehr spröder Code. Ja, es zu testen war viel schwieriger als nötig. Ja, das Ändern der Funktionalität hat Angst ausgelöst, und das Einfügen von Kopien war aufgrund des Ansatzes eine Selbstverständlichkeit.
Aber sie konnten zumindest herausfinden, was verfügbar war, indem sie eine Klasse erstellten, oder sie konnten das tun, was sie tun mussten, ohne den Unterschied zwischen Schnittstellen, abstrakten Klassen, konkreten Klassen usw. verstehen zu müssen. Und sie mussten nichts anderes suchen als die von Intellisense zurückgegebenen Methoden oder kennen die Tabellen, in denen sich die Daten befanden.
Ich habe gegoogelt / gebissen und sogar yahoo! D, aber ich habe keine Bestätigung für dieses Problem gefunden.
Vielleicht gibt es kein Problem und mir fehlt nur etwas. Ich habe mir den Kopf zerbrochen, um eine Lösung zu finden, bei der Entwickler, die nicht mit dem tatsächlichen Verhalten / Design arbeiten, leicht herausfinden können, wie etwas zu tun ist, ohne auf externe Dokumente verweisen oder die Klassennamen in den verschiedenen Komponenten scannen zu müssen. Projekte, um das zu finden, das so klingt, als würde es funktionieren.
Das einzige, was ich mir einfallen lassen konnte, ist, dass diese mangels eines besseren Namens "Table of Content Class" nichts mehr tun, was die tatsächlichen Klassen zurückgibt (und die meisten von ihnen sind Schnittstellen, aber sie tun es nicht den Unterschied kennen oder sogar darauf achten, dass andere Entwickler die tatsächlich gewünschten Aufgaben ausführen können. Am Ende gibt es immer noch sehr große Klassen, aber es gibt fast kein Verhalten in ihnen.
Gibt es einen besseren Weg, der keine genauen Kenntnisse der mittleren Ebene erfordert, in der die eigentliche Implementierung von SOLID stattfindet?
Grundsätzlich frage ich, ob es eine Möglichkeit gibt, CRUD-Entwickler weiterhin CRUD-Entwickler in einem sehr komplexen System zu sein
Antworten:
Es scheint, dass das, was Sie beschrieben haben (dh Mitarbeiterklasse mit ALLEM möglichen Code, den Sie mit einem Mitarbeiter machen können), ein äußerst verbreitetes Muster ist, das ich persönlich ziemlich oft gesehen habe. Ein Teil dieses Codes habe ich selbst geschrieben, bevor ich es besser wusste.
Was als Klasse beginnt, die eine einzelne Entität mit überschaubaren Methoden darstellen soll, verwandelt sich in etwas, das ein Albtraum ist, weil jedes Feature und jede Version immer mehr zur gleichen Klasse hinzufügen. Dies widerspricht den SOLID-Prinzipien, nach denen Sie eine Klasse einmal schreiben und dem Drang widerstehen sollten, sie immer wieder zu ändern.
Vor einiger Zeit (bevor ich Designmuster oder SOLID entdeckte, wie sie von anderen beworben wurden) entschied ich mich für mein nächstes Projekt, die Dinge ein wenig umzudrehen. Ich habe an einem Server gearbeitet, der als Schnittstelle zwischen zwei sehr großen Plattformen diente. Anfangs war nur eine Synchronisierung der Konfiguration erforderlich, aber ich konnte sehen, dass dies ein logischer Ort für viele andere Funktionen sein würde.
Anstatt eine Klasse zu schreiben, die Methoden verfügbar macht, habe ich Klassen geschrieben, die Methoden darstellen (es stellte sich heraus, dass es sich um ein "Befehls" -Muster von GoF handelt). Anstatt die Arbeit für den Kunden zu erledigen, wurden alle meine Hauptanwendungsklassen zu dauerhaften Staatsinhabern und sie wurden viel kürzer. Jedes Mal, wenn ich dem Dienst selbst eine neue Schnittstellenmethode hinzufügen musste, erstellte ich einfach eine neue Klasse mit der Execute () -Methode, mit der alles gestartet wurde. Wenn mehrere Befehle etwas gemeinsam hatten, wurden sie von der gemeinsamen Basisklasse abgeleitet. Schließlich hatte das Ding mehr als 70 verschiedene Befehlsklassen und das gesamte Projekt war immer noch sehr überschaubar und es war tatsächlich eine Freude, daran zu arbeiten.
Ihre "TOC-Klasse" ist nicht allzu weit von dem entfernt, was ich getan habe. Ich hatte eine abstrakte Fabrik (GoF), die für die Instanziierung von Befehlen verantwortlich war. In der Factory-Klasse habe ich die meisten Details hinter der Basisklasse und den Makros im ATL-Stil versteckt. Als ein Programmierer eine Anfrage hinzufügen oder nachschlagen musste, gingen sie dort hinein und sahen nur:
Alternativ (oder zusätzlich zu) können Sie alle Ihre tatsächlichen Befehlsklassen in einem separaten Namespace ablegen. Wenn also Benutzer codieren und etwas ausführen müssen, geben sie einfach den Namespace-Namen ein und Intellisense listet alle von Ihnen definierten Befehle auf. Dann enthält jeder Befehl alle get / set-Methoden, die genau bestimmen, welche Eingabe- und Ausgabeparameter vorliegen.
Sie können auch die Verwendung des Fassadenmusters (GoF) untersuchen. Anstatt mehr als 1000 Klassen Ihren CRUD-Ingenieuren auszusetzen. Verstecken Sie sie alle hinter einer einzigen Klasse, die nur das enthüllt, was benötigt wird. Ich würde mich immer noch daran halten, dass jede "Aktion" eine eigene Klasse ist, aber Ihre Facade-Klasse kann Methoden haben, die jede Ihrer Aktionen instanziieren, und mit Intellisense würden sie sofort sehen, was verfügbar ist. Oder lassen Sie Facade über tatsächliche Methoden verfügen, lassen Sie sie jedoch intern Befehle instanziieren, in die Warteschlange stellen und auf Antworten warten. Kehren Sie dann zurück, als ob ein regulärer Methodenaufruf durchgeführt wurde.
(*) Ich wollte nicht auf zu viele Details eingehen, aber ich hatte tatsächlich die Klassen "Command" und "CommandHandler". Dies trennte die Verantwortung für das Verwalten / Einreihen / Serialisieren von In / Out-Parametern von Klassen, die diese Befehle tatsächlich "handhabten".
quelle
Es kann ein Problem sein. Besonders wenn Sie Dinge schlecht benennen. Es gibt jedoch eine Reihe von Lösungen, ohne auf komplexe Klassen zurückzugreifen. Heck, eine Klasse mit zu vielen Methoden kann ebenso schwierig mit Intellisense zu navigieren sein.
Versuchen Sie, Namespaces (C #) oder Pakete (Java) oder ein ähnliches Konzept Ihrer Sprache zu verwenden (ich werde sie alle als Namespaces bezeichnen), um das Problem zu vereinfachen.
Beginnen Sie mit Ihrem Firmennamen. Das beschränkt Intellisense nur auf von Ihnen selbst geschriebene Namespaces. Wenn Sie dann mehrere Anwendungen haben, verwenden Sie den zweiten Teil des Namespace, um diese aufzuteilen. Fügen Sie einen Core-Namespace für Anwendungen hinzu, die anwendungsübergreifend vorhanden sind. Als nächstes teilen Sie die Dinge in Arten von Funktionen. Und so weiter.
Wenn Sie dies richtig machen, erhalten Sie sehr auffindbare Gegenstände.
Um Ihr Beispiel zu nehmen: Wenn ich die Benutzerüberprüfung möchte, gebe ich "MyCo" ein. und es gibt mir eine Liste von Anwendungsnamespaces. Ich weiß, dass die Benutzerdatenbank in allen unseren Apps verwendet wird, also gebe ich "Core" ein. dann bekomme ich eine Liste der Arten von Funktionen. Eine davon ist "Validierung", so dass dies eine naheliegende Wahl zu sein scheint. Und innerhalb von Validation gibt es "UserValidator" mit all seinen Funktionen.
Für Dinge, die ich oft benutze, werde ich mich schnell an die Namen oder zumindest an die Konventionen erinnern. Da ich viele Änderungen an den Validierungsregeln vornehme, weiß ich, dass alle meine Validierungsklassen FooValidator heißen, wobei Foo der Name der Tabelle ist. Ich muss also die Namespaces nicht durchqueren. Ich gebe einfach UserValidator ein und lasse die IDE den Rest der Arbeit erledigen.
Aber für Dinge, an die ich mich nicht erinnern kann, ist es immer noch ziemlich einfach, sie zu finden. Und wenn ich das tue, kann ich das Namespace-Präfix entfernen.
quelle
Da Sie sie als "CRUD" -Entwickler bezeichnen, gehen wir davon aus, dass Sie sie nicht für sehr gut halten. Wir wissen nicht, ob dies bedeutet, dass sie auch Ihre Geschäftsdomäne nicht verstehen. Wenn sie die Domäne verstehen, sollten die Klassen für sie sinnvoll sein. Da sie wissen, dass mehrere Klassen erstellt wurden, sollten sie zuerst einen Blick darauf werfen, zweitens fragen und als dritte Option das Erstellen von Grund auf in Betracht ziehen.
Wenn man weiß, wie man automatisch weiß, wie man eine Klasse verwendet / wiederverwendet, sollte man nicht beim ersten Mal damit rechnen. Sie müssen entweder durch Schulung oder möglicherweise während der Codeüberprüfung dokumentieren und möglicherweise zusätzliche Erklärungen abgeben.
Viele APIs und Open Source-Projekte bieten Dokumentation, Codebeispiele und andere Erklärungen. Ihre müssen möglicherweise nicht so benutzerfreundlich sein, aber es führt kein Weg daran vorbei. Lehre sie gut.
quelle