In unserer täglichen Entwicklung müssen wir oft einige Prinzipien und Muster befolgen. Diese werden tatsächlich von Vorgängern in der Entwicklung zusammengefasst, egal welche Softwareentwicklung wir durchführen, sie wird für uns nützlich und harmlos sein, und wir haben sie gemeistert. Diese Prinzipien und Techniken werden Ihnen nur dabei helfen, Ihre Effizienz zu verbessern. Dieser Artikel fasst diese Prinzipien zusammen und erklärt ihre Bedeutung. Ich hoffe, dass dieser Artikel Sie inspirieren und Ihnen helfen kann, Java-Kenntnisse zu verbessern. Apache PHP MySQL
beginnen!
Die Grundprinzipien (fest) der Objektorientierung sind fünf, aber zusätzlich zu diesen gibt es noch weitere die oft erwähnt werden. Zusätzlich zu den fünf gibt es das Demeter-Gesetz und das Prinzip der Synthese und Wiederverwendung usw., daher gibt es in allgemeinen Artikeln sechs oder sieben Prinzipien, außerdem werde ich auch einige andere verwandte Bücher und Informationen geben im Internet. Neue Prinzipien; Sache, nur einer bewirkt, dass es sich ändert. Das Prinzip der Einzelverantwortung kann als Erweiterung des objektorientierten Prinzips der geringen Kopplung und hohen Kohäsion angesehen werden. Verantwortung wird als Ursache für Veränderungen definiert, um den Zusammenhalt zu verbessern und die Ursache für Veränderungen zu verringern.
Prinzipienanalyse
Je mehr Verantwortlichkeiten eine Klasse (oder so groß wie ein Modul oder so klein wie eine Methode) trägt, desto unwahrscheinlicher ist es, dass sie wiederverwendet wird. und wenn eine Klasse zu viele Verantwortlichkeiten übernimmt, ist dies gleichbedeutend mit der Verknüpfung dieser Verantwortlichkeiten. Wenn sich eine der Verantwortlichkeiten ändert, kann dies Auswirkungen auf die Funktionsweise anderer Verantwortlichkeiten haben.
Die Verantwortlichkeiten einer Klasse umfassen hauptsächlich zwei Aspekte: Datenverantwortung und Verhaltensverantwortung. Datenverantwortung wird durch ihre Attribute widergespiegelt, während Verhaltensverantwortung durch ihre Methoden widergespiegelt wird.
Das Prinzip der Einzelverantwortung ist eine Richtlinie zum Erreichen einer hohen Kohäsion und einer geringen Kopplung. Es ist das einfachste, aber am schwierigsten anzuwendende Prinzip erfordert von Designern, die verschiedenen Verantwortlichkeiten einer Klasse zu erkennen und diese zu trennen, und um mehrere Verantwortlichkeiten einer Klasse zu entdecken, müssen Designer über ausgeprägte Analyse- und Designfähigkeiten sowie einschlägige Refactoring-Erfahrung verfügen.
Vorteile
Reduzieren Sie die Komplexität der Klasse und die Verantwortlichkeiten der Klasse sind klar und deutlich. Beispielsweise sind Datenverantwortung und Verhaltensverantwortung klar und deutlich.
Verbesserung der Lesbarkeit und Wartbarkeit der Klasse,
Reduzierung des durch Änderungen verursachten Risikos. Änderungen sind unerlässlich, wenn die Schnittstelle eine Einzelverantwortung hat Wenn dies gut gemacht ist, wirkt sich eine Schnittstellenänderung nur auf die entsprechende Klasse aus und hat keine Auswirkungen auf andere Schnittstellen. Dies ist eine große Hilfe für die Skalierbarkeit und Wartbarkeit des Systems.
Beispiel
Open - Closed-Prinzip,OCP, offen für Erweiterung, geschlossen für Änderung (Kernprinzip des Entwurfsmusters)OOpen-Closed-Prinzip OCP
Prinzipienanalyse
Wenn sich Softwareeinheiten aufgrund von Anforderungen ändern, versuchen Sie, vorhandene Softwareeinheiten zu erweitern, um neue Verhaltensweisen bereitzustellen, um den Anforderungen der Software gerecht zu werden Anforderungen zu erfüllen, anstatt vorhandenen Code zu ändern, sodass die sich ändernde Software ein gewisses Maß an Anpassungsfähigkeit und Flexibilität aufweist. Bestehende Softwaremodule, insbesondere die wichtigsten Module der Abstraktionsschicht, können nicht geändert werden, was dem sich ändernden Softwaresystem ein gewisses Maß an Stabilität und Kontinuität verleiht.
Der Schlüssel zur Verwirklichung des Open-Closed-Prinzips ist die Abstraktion: Im „Open-Closed“-Prinzip dürfen abstrakte Klassen oder Schnittstellen nicht geändert werden und konkrete Implementierungsklassen sind zulässig ,Abstrakte Klassen und Schnittstellen spielen eine äußerst wichtige Rolle im „Offen-Geschlossen“-Prinzip. Das heißt, mögliche sich ändernde Anforderungen vorherzusagen und alle möglichen bekannten Erweiterungen vorherzusehen. „Abstraktion“ ist hier also der Schlüssel >
Das geschlossene Prinzip der Variabilität: Finden Sie die variablen Faktoren des Systems und kapseln Sie sie. Dies ist die beste Umsetzung des „offen-geschlossenen“ Prinzips. Legen Sie Ihre variablen Faktoren nicht in mehrere Klassen , oder in jeder Ecke des Programms verstreut. Sie sollten die variablen Faktoren, die Sie verwenden, nicht zusammen kapseln. Die beste Lösung besteht darin, das Erscheinen von variablen Faktoren zu vermeiden Supergroße Klassen, superlange Klassen und superlange Methoden!! Fügen Sie Ihrem Programm eine künstlerische Note hinzu, und das Programm künstlerisch zu gestalten ist unser Ziel
Beispiel
Bei den Entwurfsmustern sind sowohl das Vorlagenmethodenmuster als auch das Beobachtermuster hervorragende Ausführungsformen des Öffnungs- und Schließprinzips. Klicken Sie hier, um detaillierte Erläuterungen zu 9 Lösungen für das Design hochverfügbarer Architektur anzuzeigen.
Liskov-Substitutionsprinzip, LSP: Überall dort, wo eine Basisklasse erscheinen kann, kann auch eine Unterklasse erscheinen als Einschränkungsspezifikation für den Vererbungsmechanismus. Nur wenn eine Unterklasse ihre Basisklasse ersetzen kann, kann garantiert werden, dass das System die Unterklasse während der Laufzeit erkennt. Dies ist die Grundlage für die Sicherstellung der Wiederverwendung der Vererbung.
Definition
Die erste Art der Definition ist relativ streng: Wenn es für jedes Objekt o1 vom Typ S ein Objekt o2 vom Typ T gibt, so dass alle mit T definierten Objekte Wenn alle Objekte o1 von Programm P durch o2 ersetzt werden, ändert sich das Verhalten von Programm P nicht, dann ist Typ S ein Untertyp von Typ T.
Die zweite, leichter verständliche Definition: Alle Stellen, die auf die Basisklasse (Elternklasse) verweisen, müssen in der Lage sein, Objekte ihrer Unterklassen transparent zu verwenden. Das heißt, die Unterklasse muss in der Lage sein, die Basisklasse dort zu ersetzen, wo sie erscheint. Unterklassen können auch neue Verhaltensweisen basierend auf der Basisklasse hinzufügen.
(Das Liskov-Substitutionsprinzip wurde 1994 von Barbara Liskov vorgeschlagen, der Gewinnerin des Turing-Preises 2008, der ersten weiblichen Doktorandin in Informatik in den Vereinigten Staaten, Professorin am MIT und Professorin Jeannette Wing an der Carnegie Der Originaltext lautet wie folgt: Sei q(x) eine beweisbare Eigenschaft von Objekten x vom Typ T. Dann sollte q(y) für Objekte y vom Typ S wahr sein, wobei S ein Untertyp von T ist. )
Prinzipanalyse
befasst sich mit der Beziehung zwischen Basisklassen und Unterklassen. Nur wenn diese Beziehung besteht, existiert das Liskov-Substitutionsprinzip. Ein Quadrat ist ein Rechteck ist ein klassisches Beispiel für das Verständnis des Liskov-Substitutionsprinzips.
Das Liskov-Substitutionsprinzip kann auf eine beliebte Weise ausgedrückt werden: Wenn Sie Basisklassenobjekte in Software verwenden können, müssen Sie in der Lage sein, deren Unterklassenobjekte zu verwenden. Wenn die Basisklasse durch ihre Unterklassen ersetzt wird, generiert das Programm keine Fehler oder Ausnahmen. Das Gegenteil ist nicht der Fall. Wenn eine Software-Entität eine Unterklasse verwendet, kann sie die Basisklasse möglicherweise nicht verwenden.
Das Liskov-Substitutionsprinzip ist eine der wichtigen Möglichkeiten, das Öffnungs- und Schließprinzip zu implementieren. Da Unterklassenobjekte überall dort verwendet werden können, wo Basisklassenobjekte verwendet werden, sollten auch Basisklassen verwendet werden Geben Sie so viel wie möglich in das Programm ein, um das Objekt zu definieren, bestimmen Sie dann zur Laufzeit seinen Unterklassentyp und ersetzen Sie das übergeordnete Klassenobjekt durch das Unterklassenobjekt.
(Schnittstellentrennungsprinzip, ISL): Der Client sollte sich nicht auf Schnittstellen verlassen, die er nicht benötigt . (Dieses Gesetz steht im Einklang mit dem Demeter-Gesetz)
Definition
Der Client sollte sich nicht auf Schnittstellen verlassen, die er nicht benötigt.
Eine andere Definitionsmethode: Sobald eine Schnittstelle zu groß ist, muss sie in kleinere Schnittstellen unterteilt werden. Clients, die die Schnittstelle verwenden, müssen nur die damit verbundenen Methoden kennen.
Beachten Sie, dass sich die Schnittstelle in dieser Definition auf die definierte Methode bezieht. Zum Beispiel das Aufrufen einer öffentlichen Methode einer Klasse von außen. Bei dieser Methode handelt es sich um eine Schnittstelle zur Außenwelt.
Prinzipanalyse
1) Das Prinzip der Schnittstellenisolation bezieht sich auf die Verwendung mehrerer spezialisierter Schnittstellen anstelle der Verwendung einer einzigen Gesamtschnittstelle. Jede Schnittstelle sollte eine relativ unabhängige Rolle einnehmen, nicht mehr und nicht weniger. Sie sollte nichts tun, was sie nicht tun sollte, sondern alles tun, was sie tun sollte.
Eine Schnittstelle repräsentiert nur eine Rolle, und jede Rolle hat ihre eigene spezifische Schnittstelle. Dieses Prinzip kann als „Rollenisolationsprinzip“ bezeichnet werden.
Die Schnittstelle stellt nur die Verhaltensweisen bereit, die der Client benötigt, dh die erforderlichen Methoden. Die Verhaltensweisen, die der Client nicht benötigt, sollten mit einer separaten Schnittstelle bereitgestellt werden so klein wie möglich, anstatt eine große Gesamtschnittstelle bereitzustellen.
2) Wenn Sie das Schnittstellenisolationsprinzip zum Aufteilen einer Schnittstelle verwenden, müssen Sie zunächst das Prinzip der Einzelverantwortung erfüllen, eine Reihe verwandter Vorgänge in einer Schnittstelle definieren und die Prämisse von hoch erfüllen Zusammenhalt. Je weniger Methoden in der Schnittstelle vorhanden sind, desto besser.
3) Beim Entwerfen des Systems können benutzerdefinierte Dienste verwendet werden, d.
Das Abhängigkeitsinversionsprinzip sollte eher auf Abstraktion als auf spezifischer Implementierung beruhen. Insbesondere sind High-Level-Module nicht auf Low angewiesen -Level-Module, die beide von Abstraktionen abhängen. Abstraktion hängt nicht vom Konkreten ab, Konkretes hängt von der Abstraktion ab.
Definition
High-Level-Module sollten nicht von Low-Level-Modulen abhängen, sie sollten alle von Abstraktionen abhängen. Abstraktionen sollten nicht von Details abhängen, Details sollten von Abstraktionen abhängen. Einfach ausgedrückt erfordert das Abhängigkeitsinversionsprinzip, dass Clients auf abstrakte Kopplungen angewiesen sind. Hauptausdruck:
1) Abstraktion sollte nicht von Details abhängen; Details sollten von Abstraktion abhängen
2) Die Programmierung sollte für Schnittstellen erfolgen, nicht für die Implementierung.
Prinzipanalyse
1) Wenn das Öffnungs- und Schließprinzip das Ziel des objektorientierten Designs ist, ist das Abhängigkeitsinversionsprinzip das Mittel, um das „Öffnungs- und Schließprinzip“ des Objekts zu erreichen. orientiertes Design. Wenn Sie das beste Prinzip des „Öffnens und Schließens“ erreichen möchten, müssen Sie sich so weit wie möglich an das Prinzip der Abhängigkeitsumkehr halten. Man kann sagen, dass das Abhängigkeitsinversionsprinzip die beste Spezifikation für „Abstraktion“ ist! Ich persönlich bin der Meinung, dass das Abhängigkeitsinversionsprinzip auch eine Ergänzung zum Richter-Substitutionsprinzip ist. Sobald Sie das Liskov-Substitutionsprinzip verstanden haben, sollte es Ihnen leicht fallen, das Abhängigkeitsinversionsprinzip zu verstehen.
2) Eine der gängigen Methoden zur Implementierung des Abhängigkeitsinversionsprinzips besteht darin, abstrakte Klassen im Code zu verwenden und konkrete Klassen in der Konfigurationsdatei zu platzieren.
3) Kopplung zwischen Klassen: Nullkopplungsbeziehung, konkrete Kopplungsbeziehung, abstrakte Kopplungsbeziehung. Das Abhängigkeitsinversionsprinzip erfordert, dass sich Clients auf abstrakte Kopplung verlassen, und zwar auf abstrakte Weise. Dies ist der Schlüssel zum Abhängigkeitsinversionsprinzip.
Beispiel
Um diese Abhängigkeitsumkehr zu verstehen, müssen wir zunächst das Konzept der Abhängigkeit im objektorientierten Design verstehen:
Abhängigkeit: Es handelt sich um eine Nutzungsbeziehung, bestimmte Dinge Änderungen können sich auf andere Dinge auswirken, die dieses Ding verwenden. Verwenden Sie Abhängigkeitsbeziehungen, wenn Sie angeben müssen, dass ein Ding ein anderes Ding verwendet. (Angenommen, dass Änderungen in Klasse A Änderungen in Klasse B verursachen, dann sagt man, dass Klasse B von Klasse A abhängt.) In den meisten Fällen spiegelt sich die Abhängigkeitsbeziehung in der Methode einer bestimmten Klasse wider, indem ein Objekt einer anderen Klasse als Parameter verwendet wird . In UML werden Abhängigkeitsbeziehungen durch gestrichelte Linien mit Pfeilen dargestellt, die von der abhängigen Partei zur abhängigen Partei zeigen.
Beispiel: Ein bestimmtes System stellt ein Datenkonvertierungsmodul bereit, das Daten aus verschiedenen Datenquellen in mehrere Formate konvertieren kann, beispielsweise Daten aus einer Datenbank (DatabaseSource) oder Daten aus einer Textdatei (TextSource), dem konvertierten Format kann eine XML-Datei (XMLTransformer), eine XLS-Datei (XLSTransformer) usw. sein.
Aufgrund geänderter Anforderungen muss das System möglicherweise jedes Mal neue Datenquellen oder neue Dateiformate hinzufügen, wenn ein neuer Datenquellentyp oder ein neuer Dateityp hinzugefügt wird , Format muss der Quellcode der Client-Klasse MainClass geändert werden, um die neue Klasse verwenden zu können, verstößt jedoch gegen das Öffnungs- und Schließprinzip. Es wird nun nach dem Abhängigkeitsinversionsprinzip umgestaltet. Klicken Sie hier, um detaillierte Erläuterungen zu 9 Lösungen für das Design hochverfügbarer Architektur anzuzeigen.
Natürlich kann AbstractSource auch in AbstractStransformer eingefügt werden. Es gibt drei Abhängigkeitsinjektionsmethoden:
<ol class="hljs-ln list-paddingleft-2"><li><p class="hljs-ln-line"><span class="hljs-comment"><span class="hljs-comment">/** </span></span></p></li><li><p class="hljs-ln-numbers"><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> * 依赖注入是依赖AbstractSource抽象注入的,而不是具体 </span><br/></p></li><li><p class="hljs-ln-numbers"><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;">* DatabaseSource </span><br/></p></li><li><p class="hljs-ln-numbers"><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;">* </span><br/></p></li><li><p class="hljs-ln-numbers"><span class="hljs-comment" style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> */</span><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> </span><br/></p></li><li><p class="hljs-ln-numbers"><span class="hljs-keyword" style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;">abstract</span><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> </span><span class="hljs-class" style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"><span class="hljs-keyword">class</span> <span class="hljs-title">AbstractStransformer</span> </span><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;">{ </span><br/></p></li><li><p class="hljs-ln-numbers"><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> </span><span class="hljs-keyword" style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;">private</span><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> AbstractSource source; </span><br/></p></li><li><p class="hljs-ln-numbers"><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> </span><span class="hljs-comment" style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"><span class="hljs-comment">/** </span></span><br/></p></li><li><p class="hljs-ln-numbers"><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> * 构造注入(Constructor Injection):通过构造函数注入实例变量。 </span><br/></p></li><li><p class="hljs-ln-numbers"><span class="hljs-comment" style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> */</span><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> </span><br/></p></li><li><p class="hljs-ln-numbers"><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> </span><span class="hljs-function" style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">AbstractStransformer</span><span class="hljs-params">(AbstractSource source)</span></span><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;">{ </span><br/></p></li><li><p class="hljs-ln-numbers"><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> </span><span class="hljs-keyword" style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;">this</span><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;">.source = source; </span><br/></p></li><li><p class="hljs-ln-numbers"><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> } </span><br/></p></li><li><p class="hljs-ln-numbers"><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> </span><span class="hljs-comment" style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"><span class="hljs-comment">/** </span></span><br/></p></li><li><p class="hljs-ln-numbers"><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> * 设值注入(Setter Injection):通过Setter方法注入实例变量。 </span><br/></p></li><li><p class="hljs-ln-numbers"><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> * </span><span class="hljs-doctag" style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;">@param</span><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> source : the sourceto set </span><br/></p></li><li><p class="hljs-ln-numbers"><span class="hljs-comment" style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> */</span><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> </span><br/></p></li><li><p class="hljs-ln-numbers"><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> </span><span class="hljs-function" style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setSource</span><span class="hljs-params">(AbstractSource source)</span> </span><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;">{ </span><br/></p></li><li><p class="hljs-ln-numbers"><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> </span><span class="hljs-keyword" style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;">this</span><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;">.source = source; </span><br/></p></li><li><p class="hljs-ln-numbers"><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> } </span><br/></p></li><li><p class="hljs-ln-numbers"><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> </span><span class="hljs-comment" style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"><span class="hljs-comment">/** </span></span><br/></p></li><li><p class="hljs-ln-numbers"><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> * 接口注入(Interface Injection):通过接口方法注入实例变量。 </span><br/></p></li><li><p class="hljs-ln-numbers"><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> * </span><span class="hljs-doctag" style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;">@param</span><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> source </span><br/></p></li><li><p class="hljs-ln-numbers"><span class="hljs-comment" style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> */</span><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> </span><br/></p></li><li><p class="hljs-ln-numbers"><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> </span><span class="hljs-function" style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">transform</span><span class="hljs-params">(AbstractSource source )</span> </span><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;">{ </span><br/></p></li><li><p class="hljs-ln-numbers"><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> source.getSource(); </span><br/></p></li><li><p class="hljs-ln-numbers"><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> System.out.println(</span><span class="hljs-string" style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;">“Stransforming …”</span><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;">); </span><br/></p></li><li><p class="hljs-ln-numbers"><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;"> } </span><br/></p></li><li><p class="hljs-ln-numbers"><span style="font-family: "Microsoft Yahei", "Hiragino Sans GB", Helvetica, "Helvetica Neue", 微软雅黑, Tahoma, Arial, sans-serif;">}</span></p></li></ol>
(Composite/Aggregate Reuse-Prinzip, CARP): Verwenden Sie Objektkombinationen so oft wie möglich , und Es ist nicht die Vererbungsbeziehung, die den Zweck der Software-Wiederverwendung erreicht
Definition
Es wird oft als Composite-Reuse-Prinzip oder CRP bezeichnet. Versuchen Sie, Objektkombination anstelle von Vererbung zu verwenden Wiederverwendungszweck zu erreichen.
besteht darin, einige vorhandene Objekte in einem neuen Objekt zu verwenden, um sie zu einem Teil des neuen Objekts zu machen. Durch Delegierung an diese Objekte wird der Zweck der Wiederverwendung vorhandener Funktionen erreicht. Kurz gesagt: Versuchen Sie, Zusammensetzung/Aggregation zu verwenden und keine Vererbung zu verwenden.
Prinzipielle Analyse
1) Beim objektorientierten Design können vorhandene Designs und Implementierungen in verschiedenen Umgebungen durch zwei grundlegende Methoden wiederverwendet werden, nämlich durch Kombinations-/Aggregationsbeziehungen oder durch Vererbung.
Vererbung und Wiederverwendung: einfach zu implementieren und leicht zu erweitern. Zerstört die Kapselung des Systems; die von der Basisklasse geerbte Implementierung ist statisch, kann zur Laufzeit nicht geändert werden und verfügt nicht über genügend Flexibilität, sodass sie nur in begrenzten Umgebungen verwendet werden kann. („White-Box“-Wiederverwendung)
Kombinations-/Aggregationswiederverwendung: Der Kopplungsgrad ist relativ gering und die Operationen von Mitgliedsobjekten werden selektiv zur Laufzeit aufgerufen; („Black-Box“-Wiederverwendung)
2) Kombination/Aggregation kann das System flexibler machen, die Kopplung zwischen Klassen verringern und Änderungen in einer Klasse haben relativ geringe Auswirkungen auf andere Klassen, also im Allgemeinen Die erste Wahl besteht darin, eine Kombination/Aggregation zu verwenden, um eine Wiederverwendung zu erreichen. Zweitens müssen Sie bei der Verwendung der Vererbung das Liskov-Ersetzungsprinzip strikt befolgen, um das Problem zu verstehen und die Komplexität zu verringern Aufgrund der Schwierigkeit des Systemaufbaus und der Systemwartung sowie der Komplexität des Systems muss die Wiederverwendung von Vererbungen mit Vorsicht angewendet werden.
3) Dieses Prinzip und das Liskov-Substitutionsprinzip ergänzen sich. Beide sind Vorgaben für die konkrete Umsetzung des „Offen-Geschlossen“-Prinzips. Bei einem Verstoß gegen dieses Prinzip kann das „Offen-Geschlossen“-Prinzip nicht realisiert werden. Zunächst müssen wir die Konzepte der Synthese und Aggregation verstehen:
Hinweis: Was ist der Unterschied zwischen Aggregation und Kombination?
Synthese (Kombination): Zeigt die Beziehung zwischen einem Ganzen und einem Teil an und bezieht sich auf eine Beziehung, die auf dem Ganzen beruht (das Ganze und die Teile können beispielsweise nicht getrennt werden). denn der Kopf, und ohne den Kopf gäbe es keine Augen und Mund, sie sind untrennbar miteinander verbunden. In UML werden Kompositionsbeziehungen durch gerade Linien mit durchgezogenen Rauten dargestellt.
Aggregation: Aggregation ist eine stärkere Abhängigkeitsbeziehung als eine Kompositionsbeziehung und stellt auch die Beziehung zwischen dem Ganzen und dem Teil dar (das Ganze und der Teil können wie die Beziehung getrennt werden). Zwischen Schrauben und Autospielzeug kann das Spielzeug nach dem Lösen der Schrauben weiterhin an anderen Geräten verwendet werden. In UML werden Aggregationsbeziehungen durch gerade Linien mit hohlen Rauten dargestellt.
Gesetz von Demeter
(Gesetz von Demeter, LoD: Klassen im System, versuchen Sie, nicht mit anderen Klassen zu interagieren, reduzieren Sie die Klassen Der Grad der Kopplung zwischen
wird in mehreren Formen definiert:
Jedes Objekt, das eine der oben genannten Bedingungen erfüllt, ist ein „Freund“ des aktuellen Objekts, ansonsten ist es ein „Fremder“:
Enger Sinn des Dimit-Gesetzes: Es kann die Kopplung zwischen Klassen reduzieren, aber es wird dem System eine große Anzahl kleiner Methoden hinzufügen und diese in alle verstreuen Die Ecke des Systems kann das lokale Design eines Systems vereinfachen, da nicht jeder Teil in direktem Zusammenhang mit entfernten Objekten steht. Dadurch wird jedoch auch die Kommunikationseffizienz zwischen Modulen verringert, was die Koordinierung zwischen verschiedenen Modulen erschwert des Systems. Klicken Sie hier, um detaillierte Erklärungen zu 9 Lösungen für das Design hochverfügbarer Architektur anzuzeigen
Der Hauptzweck des Demeter-Gesetzes besteht darin, die Informationsüberflutung zu kontrollieren.
Versuchen Sie, nicht mit anderen Klassen im System zu interagieren, um die Kopplung zwischen Klassen zu verringern, da Sie in Ihrem System beim Erweitern möglicherweise diese Klassen und zwischen Klassen ändern müssen Die Beziehung zwischen ihnen bestimmt die Komplexität von Je mehr Interaktionen vorhanden sind, desto größer ist die Schwierigkeit der Modifikation. Im Gegenteil, wenn die Interaktionen kleiner sind, ist die Schwierigkeit der Modifikation geringer. Beispielsweise hängt Klasse A von Klasse B und Klasse B von Klasse C ab. Wenn Sie Klasse A ändern, müssen Sie berücksichtigen, ob Klasse B betroffen ist und ob sich die Auswirkungen von Klasse B auf Klasse C auswirken. Wenn Klasse C zu diesem Zeitpunkt von Klasse D abhängt, haha, denke ich, dass solche Änderungen erträglich sein werden.
Andere Prinzipien des objektorientierten Designs
Änderungen kapseln
Verwendung weniger Vererbung Mehrzweckkomposition
Auf Schnittstellenprogrammierung und nicht auf Implementierungsprogrammierung ausgerichtet
Streben nach losem Kopplungsdesign zwischen interaktiven Objekten
Klassen sollten für die Entwicklung und Änderung von Erweiterungen geschlossen sein (offen). und geschlossenes OCP-Prinzip)
Verlassen Sie sich auf Abstraktionen, verlassen Sie sich nicht auf konkrete Klassen (Dependency Inversion DIP-Prinzip)
Close Friend-Prinzip: Sprechen Sie nur mit Freunden (Least Knowledge-Prinzip, Demeter-Gesetz)
Beschreibung: Ein Objekt sollte so wenig wie möglich über andere Objekte wissen, Methodenaufrufe in Grenzen halten und nur Methoden aufrufen, die zum folgenden Bereich gehören: Das Objekt selbst (lokale Methoden) Die Komponenten des Objekts sind als Methodenparameter übergeben Objekt Jedes von dieser Methode erstellte oder instanziierte Objekt
Komm nicht zu mir (ruf mich an), ich werde zu dir kommen (ruf dich an) (Hollywood-Prinzip)
A Klasse hat nur eine Ursache, die dazu führt, dass sie sich ändert (Single Responsibility SRP-Prinzip)
Können Sie das Liskov-Substitutionsprinzip erklären?
Strenge Definition: Wenn für jedes Objekt o1 Vom Typ S gibt es ein Objekt o2 vom Typ T, das das Verhalten aller mit T definierten Programme P unverändert lässt. Wenn alle Objekte durch o1 durch o2 ersetzt werden, ist Typ S ein Untertyp vom Typ T.
Beliebter Ausdruck: Alle Orte, die auf eine Basisklasse (Elternklasse) verweisen, müssen in der Lage sein, Objekte ihrer Unterklassen transparent zu verwenden. Das heißt, eine Unterklasse kann die Funktionen der übergeordneten Klasse erweitern, die ursprünglichen Funktionen der übergeordneten Klasse jedoch nicht ändern. Es enthält die folgenden 4 Bedeutungsebenen:
Eine Unterklasse kann die abstrakte Methode der übergeordneten Klasse implementieren, aber die nicht abstrakte Methode der übergeordneten Klasse nicht überschreiben.
Unterklassen können ihre eigenen einzigartigen Methoden hinzufügen.
Wenn eine Methode einer Unterklasse eine Methode einer übergeordneten Klasse überschreibt, sind die Vorbedingungen der Methode (dh die formalen Parameter der Methode) lockerer als die Eingabeparameter der Methode der übergeordneten Klasse.
Wenn eine Methode einer Unterklasse eine abstrakte Methode einer übergeordneten Klasse implementiert, sind die Nachbedingungen der Methode (d. h. der Rückgabewert der Methode) strenger als die der übergeordneten Klasse.
Unter welchen Umständen würde gegen das Demeter-Gesetz verstoßen? Warum ist das ein Problem?
Demit's Law empfiehlt, „nur mit Freunden zu sprechen, nicht mit Fremden“, um die Kopplung zwischen den Klassen zu verringern.
Geben Sie mir ein Beispiel für ein Designmuster, das dem Offen-Geschlossen-Prinzip entspricht?
Das Open-Closed-Prinzip erfordert, dass Ihr Code für Erweiterungen offen und für Änderungen geschlossen ist. Das heißt, wenn Sie eine neue Funktion hinzufügen möchten, können Sie ganz einfach neuen Code hinzufügen, ohne den bereits getesteten Code zu ändern. Es gibt mehrere Entwurfsmuster, die auf dem Open-Close-Prinzip basieren, beispielsweise das Strategiemuster. Wenn Sie eine neue Strategie benötigen, müssen Sie nur die Schnittstelle implementieren und Konfigurationen hinzufügen, ohne die Kernlogik zu ändern. Ein funktionierendes Beispiel ist die Methode Collections.sort(). Sie basiert auf dem Strategiemuster und folgt dem Open-Closed-Prinzip. Sie müssen die Methode sort() lediglich implementieren eigene Comparator-Schnittstelle.
Wann sollte der Fliegengewichtsmodus (Fliegengewichtsmodus) verwendet werden?
Der Fliegengewichtsmodus vermeidet die Erstellung zu vieler Objekte durch das Teilen von Objekten. Um das Fliegengewichtsmuster verwenden zu können, müssen Sie sicherstellen, dass Ihre Objekte unveränderlich sind, damit Sie sie sicher teilen können. Der String-Pool, der Integer-Pool und der Long-Pool im JDK sind gute Beispiele für die Verwendung des Flyweight-Musters.
Ende:
Wenn Sie Fragen haben, können Sie diese stellen und wir lassen sie uns gemeinsam besprechen.
Verwandte Artikel:
Grundkenntnisse, die JavaScript kennen muss
24 Entwurfsmuster und 7 Prinzipien in Java
Ähnliche Videos:
Das obige ist der detaillierte Inhalt vonKennen alle Java-Architekten diese 6 Designprinzipien? Muss beherrschen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!