Führt das Befolgen von SOLID dazu, dass ein Framework auf den Tech-Stack geschrieben wird?

70

Ich mag SOLID, und ich versuche mein Bestes, es zu verwenden und anzuwenden, wenn ich mich entwickle. Ich habe jedoch das Gefühl, dass der SOLID-Ansatz Ihren Code in 'Framework'-Code verwandelt - dh Code, den Sie entwerfen würden, wenn Sie ein Framework oder eine Bibliothek für andere Entwickler erstellen würden.

Ich habe im Allgemeinen 2 Programmiermodi geübt - mehr oder weniger genau das zu erstellen, was über Anforderungen und KISS (typische Programmierung) verlangt wird, oder sehr generische und wiederverwendbare Logik, Dienste usw. zu erstellen, die die Flexibilität bieten, die andere Entwickler benötigen (Framework-Programmierung). .

Wenn der Benutzer wirklich nur möchte, dass eine Anwendung x- und y-Dinge ausführt, ist es sinnvoll, SOLID zu folgen und eine ganze Reihe von Einstiegspunkten für die Abstraktion hinzuzufügen, wenn Sie nicht einmal wissen, ob dies überhaupt ein gültiges Problem ist mit? Wenn Sie diese Einstiegspunkte der Abstraktion hinzufügen, erfüllen Sie wirklich die Benutzeranforderungen oder erstellen Sie ein Framework auf der Grundlage Ihres vorhandenen Frameworks und des Tech-Stacks, um zukünftige Erweiterungen zu vereinfachen? In welchem ​​Fall dienen Sie den Interessen des Kunden oder des Entwicklers?

Dies scheint in der Java Enterprise-Welt üblich zu sein, in der Sie das Gefühl haben, ein eigenes Framework auf der Grundlage von J2EE oder Spring zu entwerfen, damit es eine bessere Benutzeroberfläche für den Entwickler darstellt, anstatt sich auf die Benutzeroberfläche für den Benutzer zu konzentrieren.

Igneous01
quelle
12
Das Problem bei den meisten kurzen Programmierregeln besteht darin, dass sie interpretiert werden können, Randfälle auftreten und manchmal die Definitionen von Wörtern in solchen Regeln bei näherer Betrachtung unklar sind. Sie können im Grunde genommen für verschiedene Menschen eine Vielzahl von Dingen bedeuten. Wenn man einen nicht-ideologischen Pragmatismus hat, kann man normalerweise klügere Entscheidungen treffen.
Mark Rogers
1
Es klingt so, als ob das Befolgen von SOLID-Grundsätzen eine große Investition und viel zusätzliche Arbeit bedeutet. Es ist praktisch kostenlos. Und es wird Ihnen oder anderen wahrscheinlich eine große Investition in die Zukunft ersparen, da Ihr Code einfacher zu warten und zu erweitern ist. Sie fragen weiter: "Sollen wir unsere Hausaufgaben machen oder den Kunden glücklich machen?" Dies sind keine Kompromisse.
Martin Maat
1
@MartinMaat Ich denke, dass die extremeren Formen von SOLID große Investitionen bedeuten. Dh Unternehmenssoftware. Außerhalb von Unternehmenssoftware hätten Sie kaum einen Grund, Ihren ORM, Ihren Technologiestapel oder Ihre Datenbank zu abstrahieren, da die Wahrscheinlichkeit sehr groß ist, dass Sie an Ihrem gewählten Stapel festhalten. Wenn Sie sich an ein bestimmtes Framework, eine bestimmte Datenbank oder einen bestimmten ORM binden, brechen Sie im gleichen Sinne die SOLID-Prinzipien, weil Sie an Ihren Stack gekoppelt sind. Dieses Maß an Flexibilität von SOLID ist bei den meisten Jobs nicht erforderlich.
Igneous01
1
Siehe auch den inneren Plattformeffekt .
Maxpm
1
Den meisten Code in so etwas wie ein Framework zu verwandeln, klingt überhaupt nicht schrecklich. Es wird nur schrecklich, wenn es überarbeitet wird. Frameworks können jedoch minimal und eigensinnig sein. Ich bin mir nicht sicher, ob dies eine unvermeidbare Konsequenz der Befolgung von SOLID wäre, aber es ist definitiv eine mögliche Konsequenz, die Sie meiner Meinung nach zu schätzen wissen sollten.
Konrad Rudolph

Antworten:

84

Ihre Beobachtung ist richtig. Die SOLID-Prinzipien wurden IMHO unter Berücksichtigung wiederverwendbarer Bibliotheken oder Framework-Codes erstellt. Wenn Sie einfach allen blind folgen, ohne zu fragen, ob dies sinnvoll ist oder nicht, riskieren Sie eine Übergeneralisierung und investieren viel mehr Aufwand in Ihr System als wahrscheinlich notwendig.

Dies ist ein Kompromiss, und es bedarf einiger Erfahrung, um die richtigen Entscheidungen darüber zu treffen, wann verallgemeinert werden soll und wann nicht. Ein möglicher Ansatz besteht darin, sich an das YAGNI-Prinzip zu halten - machen Sie Ihren Code nicht "nur für den Fall" FEST - oder verwenden Sie Ihre Worte: Nicht

bietet die Flexibilität , andere Entwickler können müssen

Stellen Sie stattdessen die Flexibilität bereit, die andere Entwickler tatsächlich benötigen , sobald sie es benötigen , jedoch nicht früher.

Wenn Sie also eine Funktion oder Klasse in Ihrem Code haben, sind Sie sich nicht sicher, ob sie wiederverwendet werden kann. Fügen Sie sie jetzt nicht in Ihr Framework ein. Warten Sie, bis Sie einen aktuellen Fall für reusage haben und Refactoring auf „SOLID genug für diesen Fall“. Implementieren Sie nicht mehr Konfigurierbarkeit (nach dem OCP) oder Einstiegspunkte der Abstraktion (mit dem DIP) in eine Klasse, die Sie für den tatsächlichen Wiederverwendungsfall wirklich benötigen. Fügen Sie die nächste Flexibilität hinzu, wenn die nächste Anforderung für die Wiederverwendung tatsächlich vorhanden ist.

Natürlich erfordert diese Arbeitsweise immer eine gewisse Umgestaltung der vorhandenen Arbeitscodebasis. Deshalb sind hier automatische Tests wichtig. Es ist also keine Zeitverschwendung, Ihren Code von Anfang an SOLID genug zu machen, um ihn auf seine Einheit testen zu können, und dies widerspricht nicht YAGNI. Automatische Tests sind ein gültiger Fall für die "Wiederverwendung von Code", da der betreffende Code sowohl aus dem Produktionscode als auch aus Tests verwendet wird. Aber denken Sie daran, fügen Sie einfach die Flexibilität hinzu, die Sie tatsächlich benötigen, um die Tests zum Laufen zu bringen, nicht weniger, nicht mehr.

Das ist eigentlich alte Weisheit. Vor langer Zeit, bevor der Begriff SOLID populär wurde, hat mir jemand gesagt, bevor wir versuchen, wieder verwendbaren Code zu schreiben , sollten wir verwendbaren Code schreiben . Und ich denke immer noch, dass dies eine gute Empfehlung ist.

Doc Brown
quelle
23
Zusätzliche Streitpunkte: Warten Sie, bis Sie drei Anwendungsfälle haben, in denen Sie dieselbe Logik sehen, bevor Sie Ihren Code für die Wiederverwendung umgestalten. Wenn Sie mit der Umgestaltung mit zwei Teilen beginnen, kann es leicht vorkommen, dass sich die Anforderungen ändern oder ein neuer Anwendungsfall die von Ihnen erstellte Abstraktion zerstört. Beschränken Sie Refaktoren auch auf Dinge mit demselben Anwendungsfall: 2 Komponenten haben möglicherweise den gleichen Code, jedoch völlig unterschiedliche Funktionen. Wenn Sie diese Komponenten zusammenführen, wird diese Logik letztendlich verknüpft, was später zu Problemen führen kann.
Nzall
8
Ich stimme dem im Allgemeinen zu, habe aber das Gefühl, dass es sich zu sehr um "einmalige" Apps handelt: Sie schreiben den Code, es funktioniert, in Ordnung. Es gibt jedoch viele Apps mit "Langzeitunterstützung". Möglicherweise schreiben Sie Code und 2 Jahre später ändern sich die Geschäftsanforderungen, sodass Sie den Code anpassen müssen. Zu diesem Zeitpunkt hängt möglicherweise noch viel anderer Code davon ab. In diesem Fall erleichtern SOLID-Prinzipien die Änderung.
R. Schmitz
3
"Bevor wir versuchen, wiederverwendbaren Code zu schreiben, sollten wir verwendbaren Code schreiben" - Sehr weise!
Graham
10
Es ist wahrscheinlich erwähnenswert, dass zu warten , bis Sie einen tatsächlicher Anwendungsfall haben Ihren SOLID Code machen besser , weil in hypothetisch arbeitet sehr schwierig ist , und Sie sind wahrscheinlich falsch erraten , was die zukünftigen Bedürfnisse sein. Unser Projekt hat eine Reihe von Fällen, in denen die Dinge SOLID und flexibel für zukünftige Bedürfnisse gestaltet wurden ... mit Ausnahme der zukünftigen Bedürfnisse, an die zu diesem Zeitpunkt noch niemand gedacht hatte, mussten wir beide umgestalten und hatten zusätzliche Flexibilität brauchte immer noch nicht - was entweder angesichts des Refactorings gewartet oder verschrottet werden musste.
KRyan
2
Außerdem müssen Sie in der Regel noch testbaren Code schreiben, was in der Regel bedeutet, dass Sie eine erste Abstraktionsebene haben, um von einer konkreten Implementierung zu einer testbaren wechseln zu können.
Walfrat
49

Nach meiner Erfahrung haben Sie beim Schreiben einer App drei Möglichkeiten:

  1. Schreiben Sie Code nur, um die Anforderungen zu erfüllen,
  2. Schreiben Sie generischen Code, der zukünftige Anforderungen antizipiert und die aktuellen Anforderungen erfüllt.
  3. Schreiben Sie Code, der nur die aktuellen Anforderungen erfüllt, aber auf eine Weise, die später leicht geändert werden kann, um andere Anforderungen zu erfüllen.

Im ersten Fall ist es üblich, eng gekoppelten Code zu erhalten, dem Unit-Tests fehlen. Sicher ist es schnell zu schreiben, aber es ist schwer zu testen. Und es ist ein richtiger Königsweg, sich später zu ändern, wenn sich die Anforderungen ändern.

Im zweiten Fall wird sehr viel Zeit aufgewendet, um zukünftige Bedürfnisse zu antizipieren. Und allzu oft werden die erwarteten zukünftigen Anforderungen nie erfüllt. Dies scheint das Szenario zu sein, das Sie beschreiben. Es ist meistens eine Verschwendung von Aufwand und führt zu unnötig komplexem Code, der immer noch schwer zu ändern ist, wenn eine Anforderung auftaucht, die nicht erwartet wurde.

Der letzte Fall ist meiner Ansicht nach der, auf den man abzielt. Verwenden Sie TDD oder ähnliche Techniken, um den Code unterwegs zu testen. Am Ende erhalten Sie locker gekoppelten Code, der einfach zu ändern und dennoch schnell zu schreiben ist. Und auf diese Weise folgen Sie natürlich vielen der SOLID-Prinzipien: kleine Klassen und Funktionen; Schnittstellen und injizierte Abhängigkeiten. Und Frau Liskov ist im Allgemeinen auch glücklich, da einfache Klassen mit Einzelverantwortung selten gegen ihr Substitutionsprinzip verstoßen.

Der einzige Aspekt von SOLID, der hier nicht wirklich zutrifft, ist das Open / Closed-Prinzip. Für Bibliotheken und Frameworks ist dies wichtig. Für eine in sich geschlossene App nicht so sehr. In Wirklichkeit handelt es sich um das Schreiben von Code, der " SLID " folgt : einfach zu schreiben (und zu lesen), einfach zu testen und einfach zu warten.

David Arno
quelle
Eine meiner Lieblingsantworten auf dieser Seite!
TheCatWhisperer
Ich bin mir nicht sicher, wie Sie zu dem Schluss kommen, dass 1) schwieriger zu testen ist als 3). Es ist sicher schwieriger, Änderungen vorzunehmen, aber warum können Sie nicht testen? Wenn überhaupt, ist es einfacher, eine eigensinnige Software gegen die Anforderungen zu testen als eine allgemeinere.
Mr Lister
@MrLister Die beiden gehen Hand in Hand, 1. ist schwieriger zu testen als 3., weil die Definition impliziert, dass es nicht "auf eine Weise geschrieben ist, die später leicht geändert werden kann, um andere Anforderungen zu erfüllen".
Mark Booth
1
+0; IMVHO Sie falsch interpretieren (wenn auch in üblicher Weise), wie 'O' (offen-geschlossen) funktioniert. Siehe z. B. codeblog.jonskeet.uk/2013/03/15/… - selbst in kleinen Codebasen geht es eher um in sich geschlossene Codeeinheiten (z. B. Klassen, Module, Pakete usw.), die isoliert getestet und hinzugefügt werden können Ich werde entfernt, wenn es nötig ist. Ein solches Beispiel wäre ein Paket von Dienstprogrammmethoden - unabhängig davon, wie Sie sie bündeln, sollten sie "geschlossen", dh in sich geschlossen und "offen", dh in irgendeiner Weise erweiterbar sein.
Vaxquis
Übrigens, sogar Onkel Bob geht diesen Weg an einem Punkt: „Was [offen-geschlossen] bedeutet, ist, dass Sie sich bemühen sollten, Ihren Code in eine Position zu bringen, in der Sie, wenn sich das Verhalten auf erwartete Weise ändert, kein Kehren vornehmen müssen Änderungen an allen Modulen des Systems. Im Idealfall können Sie das neue Verhalten hinzufügen, indem Sie neuen Code hinzufügen und wenig oder keinen alten Code ändern. “ <- Dies gilt natürlich auch für kleine Anwendungen, wenn sie jemals geändert oder repariert werden sollen (und, IMVHO, Das ist in der Regel der Fall, vor allem, wenn es um die Fixes geht ( kichern )
Vaxquis
8

Die Perspektive, die Sie haben, kann durch persönliche Erfahrung verzerrt werden. Dies ist eine schlüpfrige Anhäufung von Fakten, die individuell korrekt sind, die sich daraus ergebende Folgerung jedoch nicht, obwohl sie auf den ersten Blick korrekt aussieht.

  • Frameworks sind umfangreicher als kleine Projekte.
  • Schlechte Praktiken sind in größeren Codebasen bedeutend schwerer zu handhaben.
  • Das Erstellen eines Frameworks erfordert (im Durchschnitt) einen erfahreneren Entwickler als das Erstellen eines kleinen Projekts.
  • Bessere Entwickler befolgen bewährte Verfahren (SOLID) mehr.
  • Infolgedessen besteht bei Frameworks ein höherer Bedarf an bewährten Verfahren, und sie werden in der Regel von Entwicklern erstellt, die mit bewährten Verfahren besser vertraut sind.

Dies bedeutet, dass bei der Interaktion mit Frameworks und kleineren Bibliotheken der Code für bewährte Verfahren, mit dem Sie interagieren, häufiger in den größeren Frameworks enthalten ist.

Dieser Irrtum ist sehr verbreitet, z. B. war jeder Arzt, von dem ich behandelt wurde, arrogant. Daraus schließe ich, dass alle Ärzte arrogant sind. Diese Irrtümer leiden immer unter einer pauschalen Folgerung, die auf persönlichen Erfahrungen beruht.

In Ihrem Fall ist es möglich, dass Sie vorwiegend in größeren Frameworks und nicht in kleineren Bibliotheken gute Praxiserfahrungen gemacht haben. Ihre persönliche Beobachtung ist nicht falsch, aber es ist ein Einzelfall und nicht universell anwendbar.


2 Programmiermodi - mehr oder weniger genau das erstellen, was über Anforderungen und KISS (typische Programmierung) verlangt wird, oder sehr generische und wiederverwendbare Logik, Dienste usw. erstellen, die die Flexibilität bieten, die andere Entwickler benötigen (Rahmenprogrammierung)

Das bestätigen Sie hier ein wenig. Überlegen Sie, was ein Framework ist. Es ist keine Anwendung. Es ist eine verallgemeinerte "Vorlage", mit der andere alle Arten von Anwendungen erstellen können. Logischerweise bedeutet dies, dass ein Framework in einer viel abstrakteren Logik aufgebaut ist, um von allen genutzt werden zu können.

Framework-Builder sind nicht in der Lage, Verknüpfungen zu verwenden, da sie nicht einmal die Anforderungen der nachfolgenden Anwendungen kennen. Durch das Erstellen eines Frameworks werden sie dazu angeregt, ihren Code für andere nutzbar zu machen.

Anwendungsentwickler können jedoch Kompromisse bei der logischen Effizienz eingehen, da sie sich auf die Bereitstellung eines Produkts konzentrieren. Ihr Hauptziel ist nicht die Funktionsweise des Codes, sondern die Erfahrung des Benutzers.

Bei einem Framework ist der Endbenutzer ein anderer Entwickler, der mit Ihrem Code interagiert. Die Qualität Ihres Codes ist für Ihren Endbenutzer von Bedeutung.
Bei einer Anwendung ist der Endbenutzer kein Entwickler, der nicht mit Ihrem Code interagiert. Die Qualität Ihres Codes spielt für sie keine Rolle.

Genau aus diesem Grund setzen die Architekten eines Entwicklungsteams häufig bewährte Praktiken durch. Sie sind nur einen Schritt von der Bereitstellung des Produkts entfernt, was bedeutet, dass sie dazu tendieren, den Code objektiv zu betrachten, anstatt sich auf die Bereitstellung der Anwendung selbst zu konzentrieren.


Wenn Sie diese Einstiegspunkte der Abstraktion hinzufügen, erfüllen Sie wirklich die Benutzeranforderungen oder erstellen Sie ein Framework auf der Grundlage Ihres vorhandenen Frameworks und des Tech-Stacks, um zukünftige Erweiterungen zu vereinfachen? In welchem ​​Fall dienen Sie den Interessen des Kunden oder des Entwicklers?

Dies ist ein interessanter Punkt, und meiner Erfahrung nach ist dies der Hauptgrund, warum die Menschen immer noch versuchen, das Vermeiden bewährter Praktiken zu rechtfertigen.

Um die folgenden Punkte zusammenzufassen: Das Überspringen bewährter Verfahren kann nur gerechtfertigt werden, wenn Ihre Anforderungen (wie derzeit bekannt) unveränderlich sind und die Codebasis niemals geändert oder ergänzt wird. Spoiler Alarm: Das ist selten der Fall.
Wenn ich beispielsweise eine 5-minütige Konsolenanwendung schreibe, um eine bestimmte Datei zu verarbeiten, verwende ich keine bewährten Methoden. Da ich die Anwendung heute nur noch verwenden werde und sie in Zukunft nicht mehr aktualisiert werden muss (es wäre einfacher, eine andere Anwendung zu schreiben, wenn ich eine weitere benötige).

Angenommen, Sie können eine Anwendung in 4 Wochen problemlos und in 6 Wochen ordnungsgemäß erstellen. Auf den ersten Blick scheint es besser zu sein, schlampig zu bauen. Der Kunde erhält seine Bewerbung schneller und das Unternehmen muss weniger Zeit für Entwicklergehälter aufwenden. Win / win, richtig?

Dies ist jedoch eine Entscheidung, die ohne Vorausdenken getroffen wird. Aufgrund der Qualität der Codebasis dauert es 2 Wochen, eine größere Änderung an der fehlerfrei erstellten Codebasis vorzunehmen, während die gleichen Änderungen an der ordnungsgemäß erstellten Codebasis 1 Woche dauern. Möglicherweise werden sich in Zukunft viele dieser Änderungen ergeben.

Darüber hinaus besteht die Tendenz, dass Änderungen unerwartet mehr Arbeit erfordern, als Sie anfangs in schlecht gebauten Codebasen dachten, wodurch sich Ihre Entwicklungszeit wahrscheinlich auf drei statt auf zwei Wochen erhöht.

Und dann gibt es auch die Tendenz, Zeit für die Suche nach Fehlern zu verschwenden. Dies ist häufig bei Projekten der Fall, bei denen die Protokollierung aus Zeitgründen oder weil Sie nicht gewillt sind, sie zu implementieren, ignoriert wurde, weil Sie abwesend unter der Annahme arbeiten, dass das Endprodukt wie erwartet funktioniert.

Es muss nicht einmal ein großes Update sein. Bei meinem jetzigen Arbeitgeber habe ich mehrere Projekte gesehen, die schnell und schmutzig erstellt wurden, und als der kleinste Fehler / die kleinste Änderung aufgrund einer fehlerhaften Kommunikation in den Anforderungen vorgenommen werden musste, führte dies zu einer Kettenreaktion, die es erforderlich machte, Modul für Modul umzugestalten . Einige dieser Projekte scheiterten (und hinterließen ein unhaltbares Durcheinander), bevor sie überhaupt ihre erste Version veröffentlichten.

Verknüpfungsentscheidungen (schnelle und unsaubere Programmierung) sind nur dann von Vorteil, wenn Sie endgültig garantieren können, dass die Anforderungen genau richtig sind und sich niemals ändern müssen. Nach meiner Erfahrung bin ich noch nie auf ein Projekt gestoßen, bei dem dies zutrifft.

Die zusätzliche Zeit in bewährte Verfahren zu investieren, bedeutet, in die Zukunft zu investieren. Zukünftige Fehler und Änderungen werden so viel einfacher, wenn die vorhandene Codebasis auf bewährten Methoden aufbaut. Es zahlt sich bereits nach zwei oder drei Änderungen aus.

Flater
quelle
1
Dies ist eine gute Antwort, aber ich sollte klarstellen, dass ich nicht sage, dass wir auf bewährte Praktiken verzichten, sondern welche „bewährten Praktiken“ verfolgen wir? Ist es empfehlenswert, Ihr ORM in jedem Projekt zu abstrahieren, weil Sie es möglicherweise später gegen ein anderes austauschen müssen? Ich glaube nicht, es gibt bestimmte Ebenen der Kopplung, die ich akzeptieren möchte (dh ich bin an das Framework, die Sprache, den ORM und die Datenbank gebunden, die ausgewählt wurden). Wenn wir SOLID bis zum Äußersten folgen, implementieren wir dann wirklich nur unser eigenes Framework auf dem ausgewählten Stack?
Igneous01
Sie bestreiten die Erfahrung von OP als "Trugschluss". Nicht konstruktiv.
Max630:
@ max630 Ich bestreite es nicht. Ich habe einen Großteil der Antwort darauf verwendet, um zu erklären, warum die Beobachtungen von OP gültig sind.
Flater
1
@ Igneous01 SOLID ist kein Framework. SOLID ist eine Abstraktion, die in einem Framework häufiger vorkommt. Bei der Implementierung jeglicher Art von Abstraktion (einschließlich SOLID) gibt es immer eine Linie der Vernünftigkeit. Sie können nicht nur abstrahieren, um der Abstraktion willen, Sie würden eine Ewigkeit damit verbringen, sich Code auszudenken, der so stark verallgemeinert ist, dass es schwierig ist, ihm zu folgen. Nur eine Zusammenfassung, von der Sie vermuten, dass sie Ihnen in Zukunft nützlich sein wird. Gehen Sie jedoch nicht davon aus, dass Sie beispielsweise an Ihren aktuellen Datenbankserver gebunden sind. Sie wissen nie, welche neue Datenbank morgen veröffentlicht wird.
Flater
@ Igneous01 Mit anderen Worten, du hast die richtige Idee, indem du nicht alles abstrahieren willst, aber ich habe das Gefühl, dass du dich ein bisschen zu weit in diese Richtung neigst. Entwickler gehen häufig davon aus, dass die aktuellen Anforderungen in Stein gemeißelt sind, und treffen dann architektonische Entscheidungen, die auf dieser (Wunsch-) Annahme basieren.
Flater
7

Wie wandelt SOLID einfachen Code in Framework-Code um? Ich bin in keiner Weise ein Stan für SOLID, aber es ist wirklich nicht klar, was Sie hier meinen.

  • KISS ist die Essenz des S ingle Prinzip Verantwortung.
  • Es gibt nichts im O- Pen / Closed-Prinzip (zumindest so wie ich es verstehe - siehe Jon Skeet ), das gegen das Schreiben von Code verstößt, um eine Sache gut zu machen. (Je genauer der Code fokussiert ist, desto wichtiger wird der "geschlossene" Teil.)
  • Das L iskov-Substitutionsprinzip besagt nicht, dass Sie Ihre Klassen unterordnen müssen. Wenn Sie Ihre Klassen in Unterklassen unterteilen, müssen Ihre Unterklassen den Vertrag mit ihren Oberklassen erfüllen. Das ist einfach gutes OO-Design. (Und wenn Sie keine Unterklassen haben, gilt dies nicht.)
  • KISS ist auch das Wesen des I nterface Segregations Prinzip.
  • Das D ependency Inversion Principle ist das einzige Prinzip, das ich aus der Ferne anwenden kann, aber ich denke, es wird weitestgehend missverstanden und übertrieben. Es bedeutet nicht, dass Sie alles mit Guice oder Spring injizieren müssen. Es bedeutet nur, dass Sie gegebenenfalls abstrahieren und nicht von Implementierungsdetails abhängen sollten.

Ich gebe zu, dass ich selbst nicht in SOLID-Begriffen denke, weil ich die Programmierschulen der Gang of Four und Josh Bloch durchlaufen habe , nicht die Bob-Martin-Schule. Aber ich denke wirklich, wenn Sie denken, dass „SOLID“ = „dem Tech-Stack mehr Ebenen hinzufügen“, dann lesen Sie das falsch.


PS: Verkaufen Sie die Vorteile von "Better UX for the Developer" nicht kurz. Code verbringt den größten Teil seiner Lebensdauer mit Wartung. Ein Entwickler bist du .

David Moles
quelle
1
In Bezug auf SRP könnte man argumentieren, dass jede Klasse mit einem Konstruktor SRP verletzt, weil Sie diese Verantwortung auf eine Factory verlagern können. In Bezug auf OCP ist dies ein Problem auf Framework-Ebene, da Sie eine Schnittstelle, die für den externen Gebrauch bestimmt ist, nicht mehr ändern können. Wenn die Schnittstelle nur in Ihrem Projekt verwendet wird, ist es möglich, den Vertrag zu ändern, da Sie die Möglichkeit haben, den Vertrag innerhalb Ihres eigenen Codes zu ändern. In Bezug auf ISP - könnte man argumentieren, dass eine Schnittstelle für jede einzelne Aktion definiert werden sollte (wodurch SRP erhalten bleibt) und externe Benutzer betrifft.
Igneous01
3
1) man könnte, aber ich bezweifle, dass jemand, der es wert ist, jemals zugehört zu haben. 2) Sie werden überrascht sein, wie schnell ein Projekt zu einer Größe heranwachsen kann, bei der es eine schlechte Idee ist, interne Schnittstellen frei zu ändern. 3) siehe sowohl 1) als auch 2). Es genügt zu sagen, ich denke, Sie lesen zu viel in allen drei Prinzipien. Kommentare sind jedoch nicht der richtige Ort, um diese Argumente anzusprechen. Ich schlage vor, Sie stellen jede Frage einzeln und fragen, welche Antworten Sie erhalten.
David Moles
4
@ Igneous01 Mit dieser Logik können Sie Getter und Setter genauso gut aufgeben, da Sie für jeden Variablensetzer eine eigene Klasse und für jeden Getter eine eigene Klasse erstellen können. IE: class A{ int X; int Y; } class A_setX{ f(A a, int N) { a.X = N; }} class A_getX{ int f(A a) { return X; }} class A_setY ... etc.Ich denke, Sie betrachten es aus einer zu meta Sicht mit Ihrem Fabrikanspruch. Die Initialisierung ist kein Aspekt des Domänenproblems.
Aaron
@ Aaron Dies. Leute können SOLID benutzen, um schlechte Argumente zu machen, aber das bedeutet nicht, schlechte Dinge zu tun = "SOLID folgen".
David Moles