Mit der Zeit konnte ich zwei Teile von SOLID verstehen - das „S“ und das „O“.
"O" - Ich habe das Open Closed-Prinzip mithilfe von Vererbung und Strategiemuster gelernt.
"S" - Ich habe beim Lernen von ORM das Prinzip der Einzelverantwortung gelernt (die Persistenzlogik wird von Domänenobjekten entfernt).
In ähnlicher Weise, was sind die besten Regionen / Aufgaben, um andere Teile von SOLID zu lernen (das "L", "I" und "D")?
Verweise
Antworten:
Ich war vor ein paar Monaten in Ihren Schuhen, bis ich einen sehr hilfreichen Artikel fand.
Jedes Prinzip wird mit realen Situationen, mit denen jeder Softwareentwickler in seinen Projekten konfrontiert ist, gut erklärt. Ich schneide hier ab und zeige auf die Referenz - SOLIDE Softwareentwicklung, Schritt für Schritt .
Wie in den Kommentaren erwähnt, gibt es eine weitere sehr gute PDF-Lektüre - Pablos SOLID Software Development .
Darüber hinaus gibt es einige gute Bücher, die die SOLID-Prinzipien detaillierter beschreiben - Good Book on SOLID Software Development .
Bearbeiten und Kommentieren einer kurzen Zusammenfassung für jedes Prinzip:
Das „S“ -Prinzip (Single Responsibility Principle) richtet sich nach den Bedürfnissen des Unternehmens, um Veränderungen zu ermöglichen. „Ein einziger Grund zur Änderung“ hilft Ihnen zu verstehen, welche logisch getrennten Konzepte zusammengefasst werden sollten, indem das Geschäftskonzept und der Kontext anstelle des technischen Konzepts allein berücksichtigt werden.
In another words
Ich habe gelernt, dass jede Klasse eine einzige Verantwortung haben sollte. Die Verantwortung ist es, nur die zugewiesene Aufgabe zu erfüllen"O" - Ich lernte Open Closed Principle und begann, "Komposition vor Vererbung zu bevorzugen" und als solche Klassen zu bevorzugen, die keine virtuellen Methoden haben und möglicherweise versiegelt sind, aber für ihre Erweiterung auf Abstraktionen angewiesen sind.
"L" - Ich habe das Liskov-Substitutionsprinzip mithilfe des Repository-Musters für die Verwaltung des Datenzugriffs gelernt.
Da in den Kommentaren eine nützliche Ressource von CodePlex erwähnt wurde, wird beispielhaft auf SOLID verwiesen
quelle
(I) Interfacesegregation und (D) Ependency Inversion können durch Unit-Tests und Mocking erlernt werden. Wenn Klassen ihre eigenen Abhängigkeiten erstellen, können Sie keine guten Komponententests erstellen. Wenn sie von einer zu breiten Schnittstelle abhängen (oder überhaupt keine), ist es nicht sehr offensichtlich, was verspottet werden muss, um Ihre Komponententests durchzuführen.
quelle
Mit dem Liskov-Substitutionsprinzip können Sie die Implementierungsvererbung im Grunde genommen nicht überbeanspruchen: Sie sollten die Vererbung niemals nur zur Wiederverwendung von Code verwenden (dafür gibt es eine Komposition)! Wenn Sie sich an LSP halten, können Sie ziemlich sicher sein, dass tatsächlich eine "Ist-Beziehung" zwischen Ihrer Oberklasse und Ihrer Unterklasse besteht.
Es heißt, dass Ihre Unterklassen alle Methoden der Unterklasse auf ähnliche Weise implementieren müssen wie die Methoden der Unterklasse. Sie sollten niemals eine Methode mit der Implementierung von NOP überschreiben oder null zurückgeben, wenn der Supertyp eine Ausnahme auslöst. Gemäß den Bedingungen von Design by Contract sollten Sie den Vertrag der Methode der Oberklasse einhalten, wenn Sie eine Methode überschreiben. Ein Weg, sich gegen das Brechen dieses Prinzips zu verteidigen, besteht darin, eine implementierte Methode niemals außer Kraft zu setzen. Extrahieren Sie stattdessen eine Schnittstelle und implementieren Sie diese Schnittstelle in beiden Klassen.
Das Prinzip der Grenzflächentrennung, das Prinzip der Einzelverantwortung und das Prinzip des hohen Koehsionsvermögens von GRASP hängen irgendwie zusammen. Sie beziehen sich auf die Tatsache, dass ein Unternehmen nur für eine Sache verantwortlich sein sollte, so dass es nur einen Grund für eine Änderung gibt, so dass eine Änderung sehr einfach durchgeführt werden kann.
Tatsächlich heißt es, dass eine Klasse, wenn sie eine Schnittstelle implementiert, alle Methoden dieser Schnittstelle implementieren und verwenden muss. Wenn es Methoden gibt, die in dieser bestimmten Klasse nicht benötigt werden, ist die Schnittstelle nicht funktionsfähig und muss in zwei Schnittstellen aufgeteilt werden, eine, die nur die von der ursprünglichen Klasse benötigten Methoden enthält. Es kann von einem POV aus betrachtet werden, das sich auf das vorherige Prinzip bezieht, indem es nicht zulässt, dass Sie große Schnittstellen erstellen, sodass deren Implementierung das LSP beschädigen kann.
Sie können die Abhängigkeitsinversion im Factory-Muster sehen. Hier hängen sowohl die übergeordnete Komponente (der Client) als auch die untergeordnete Komponente (die zu erstellende Einzelinstanz) von der Abstraktion ab(die Schnittstelle). Eine Möglichkeit, es in einer Schichtenarchitektur anzuwenden: Sie sollten keine Schnittstelle zu einer Schicht in der implementierten Schicht definieren, sondern in dem Modul, das aufgerufen wird. Beispielsweise sollte die API für die Datenquellenschicht nicht in die Datenquellenschicht geschrieben werden, sondern in die Business-Logikschicht, in der sie aufgerufen werden muss. Auf diese Weise erbt die Datenquellenschicht das in der Geschäftslogik definierte Verhalten (also die Inversion) und nicht umgekehrt (wie auf normale Weise). Dies bietet Flexibilität beim Entwurf, sodass die Geschäftslogik ohne Codeänderung mit einer anderen, völlig anderen Datenquelle funktioniert.
quelle