Sie müssen sich nicht strikt an diese Grundsätze halten und es gibt keine religiösen Strafen für deren Verstöße. Aber Sie sollten sich diese Grundsätze als Alarmglocken vorstellen. Wenn einer von ihnen verletzt wird, ertönt die Alarmglocke.
(1) Alle Daten sollten innerhalb der Klasse verborgen sein, in der sie sich befinden.
(2) Benutzer einer Klasse müssen sich auf die gemeinsam genutzte Schnittstelle der Klasse verlassen, eine Klasse kann sich jedoch nicht auf ihre Benutzer verlassen.
(3) Minimieren Sie die Nachrichten im Klassenprotokoll.
(4) Implementieren Sie die grundlegendste öffentliche Schnittstelle, die alle Klassen verstehen [z. B. Kopiervorgänge (tiefe Kopie und flache Kopie), Gleichheitsbeurteilung, korrekten Ausgabeinhalt, Analyse anhand der ASCII-Beschreibung usw.].
(5) Fügen Sie keine Implementierungsdetails (z. B. private Funktionen, die gemeinsam genutzten Code platzieren) in die öffentliche Schnittstelle der Klasse ein. Wenn zwei Methoden einer Klasse einen gemeinsamen Code haben, können Sie eine private Funktion erstellen, die diesen gemeinsamen Code verhindert.
(6) Stören Sie die öffentliche Schnittstelle der Klasse nicht durch Dinge, die Benutzer nicht verwenden können oder an denen sie kein Interesse haben.
(7) Es sollte keine Kopplung zwischen Klassen oder nur abgeleitete Kopplungsbeziehungen geben. Das heißt, eine Klasse hat entweder nichts mit einer anderen Klasse zu tun oder sie verwendet nur Operationen in der öffentlichen Schnittstelle einer anderen Klasse.
(8) Eine Klasse sollte nur eine Schlüsselabstraktion darstellen. Alle Klassen im Paket sollten gemeinsam geschlossen werden, um Änderungen am gleichen Eigenschaftstyp zu verhindern. Wenn eine Änderung ein Paket betrifft, wirkt sie sich auf alle Klassen im Paket aus, hat jedoch keine Auswirkungen auf andere Pakete.
(9) Zentralisieren Sie verwandte Daten und Verhaltensweisen. Designer sollten sich der Objekte bewusst sein, die durch Operationen wie get Daten von anderen Objekten abrufen. Diese Art von Verhalten impliziert, dass dieses empirische Prinzip verletzt wird.
(10) Ordnen Sie irrelevante Informationen einer anderen Kategorie zu (d. h. dem Verhalten, nicht miteinander zu kommunizieren). Stellen Sie Abhängigkeiten zur Stabilität her.
(11) Stellen Sie sicher, dass die abstrakten Konzepte, die Sie modellieren, Klassen sind und nicht nur die Rollen, die Objekte spielen.
(12) Verteilen Sie die Systemfunktionen möglichst gleichmäßig in horizontaler Richtung, das heißt: Gemäß dem Entwurf sollten die Klassen der obersten Ebene die Arbeit gleichmäßig teilen.
(13) Erstellen Sie keine allmächtigen Klassen/Objekte in Ihrem System. Seien Sie besonders vorsichtig bei Klassen, deren Namen Driver, Manager, System und Susystem umfassen. Planen Sie eine Schnittstelle, anstatt sie zu implementieren.
(14) Seien Sie vorsichtig bei Klassen, die eine große Anzahl von Zugriffsmethoden in der öffentlichen Schnittstelle definieren. Aufgrund der Vielzahl an Zugriffsmöglichkeiten werden relevante Daten und Verhaltensweisen nicht zentral gespeichert.
(15) Seien Sie vorsichtig bei Klassen, die zu viele Verhaltensweisen enthalten, die nicht miteinander kommunizieren. Eine weitere Manifestation dieses Problems ist die Erstellung zahlreicher Get- und Set-Funktionen in der öffentlichen Schnittstelle der Klassen in Ihrer Anwendung.
(16) In einer Anwendung, die aus einem objektorientierten Modell besteht, das mit der Benutzeroberfläche interagiert, sollte das Modell nicht von der Schnittstelle abhängen, sondern die Schnittstelle sollte vom Modell abhängen.
(17) Modellieren Sie so weit wie möglich nach der realen Welt (wir verstoßen häufig gegen dieses Prinzip, um das Prinzip der Systemfunktionsverteilung einzuhalten, das Allzweckklassenprinzip zu vermeiden und relevante Daten und Verhaltensweisen zentral zu platzieren).
(18) Entfernen Sie unnötige Klassen aus Ihrem Design. Im Allgemeinen würden wir diese Klasse auf eine Eigenschaft herabstufen.
(19) Klassen außerhalb des Systems entfernen. Das Merkmal von Klassen außerhalb des Systems besteht darin, dass sie abstrakt gesehen nur Nachrichten an die Systemdomäne senden, aber keine Nachrichten von anderen Klassen in der Systemdomäne akzeptieren.
(20) Verwandeln Sie Operationen nicht in Klassen. Befragen Sie jede Klasse, deren Name ein Verb ist oder von einem Verb abgeleitet ist, insbesondere eine Klasse mit nur einer sinnvollen Aktion. Überlegen Sie, ob dieses sinnvolle Verhalten in eine Klasse verschoben werden sollte, die bereits existiert oder noch nicht entdeckt wurde.
(21) Bei der Erstellung von Analysemodellen für Anwendungen führen wir häufig Proxy-Klassen ein. Während der Entwurfsphase stellen wir häufig fest, dass viele Agenten nutzlos sind und entfernt werden sollten.
(22) Minimieren Sie die Anzahl der Mitarbeiter einer Klasse. Die Anzahl der von einer Klasse verwendeten anderen Klassen sollte auf ein Minimum beschränkt werden.
(23) Minimieren Sie die Anzahl der Nachrichten, die zwischen Klassen und Mitarbeitern ausgetauscht werden.
(24) Minimieren Sie den Umfang der Zusammenarbeit zwischen Klassen und Mitarbeitern, das heißt: Reduzieren Sie die Anzahl unterschiedlicher Nachrichten, die zwischen Klassen und Mitarbeitern ausgetauscht werden.
(25) Minimieren Sie das Fan-Out der Klasse, dh reduzieren Sie das Produkt aus der Anzahl der von der Klasse definierten Nachrichten und der Anzahl der gesendeten Nachrichten.
(26) Wenn eine Klasse ein Objekt einer anderen Klasse enthält, sollte die enthaltende Klasse eine Nachricht an das enthaltene Objekt senden. Das heißt: Eine Inklusionsrelation impliziert immer eine Nutzungsrelation.
(27) Die meisten in einer Klasse definierten Methoden sollten die meiste Zeit die meisten Datenelemente verwenden.
(28) Die Anzahl der in einer Klasse enthaltenen Objekte sollte die Kapazität des Kurzzeitgedächtnisses des Entwicklers nicht überschreiten. Diese Zahl ist oft 6. Wenn eine Klasse mehr als 6 Datenelemente enthält, können Sie logisch verwandte Datenelemente in eine Gruppe aufteilen und dann eine neue enthaltende Klasse verwenden, um diese Gruppe von Elementen aufzunehmen.
(29) Systemfunktionen seien vertikal in einem engen und tiefen Vererbungssystem verteilt.
(30) Bei der Implementierung semantischer Einschränkungen ist es am besten, diese gemäß der Klassendefinition zu implementieren. Dies führt häufig zu einem Klassenüberlauf. In diesem Fall sollten die Einschränkungen im Verhalten der Klasse implementiert werden, normalerweise, aber nicht unbedingt, im Konstruktor.
(31) Wenn Sie semantische Einschränkungen im Konstruktor einer Klasse implementieren, platzieren Sie den Einschränkungstest auf der tiefsten Inklusionsebene, die die Domäne des Konstruktors zulässt.
(32) Wenn sich die semantischen Informationen, auf denen Einschränkungen basieren, häufig ändern, ist es am besten, sie in einem zentralen Objekt eines Drittanbieters abzulegen.
(33) Wenn sich die semantischen Informationen, auf denen Einschränkungen beruhen, selten ändern, werden sie am besten auf die an den Einschränkungen beteiligten Klassen verteilt.
(34) Eine Klasse muss wissen, was sie enthält, aber sie kann nicht wissen, wer es enthält.
(35) Objekte, die einen gemeinsamen Literalbereich haben (d. h. in derselben Klasse enthalten sind), sollten keine Nutzungsbeziehung zueinander haben.
(36) Vererbung sollte nur zur Modellierung von Spezialisierungshierarchien verwendet werden.
(37) Abgeleitete Klassen müssen über Basisklassen Bescheid wissen, und Basisklassen sollten keine Informationen über ihre abgeleiteten Klassen kennen.
(38) Alle Daten in der Basisklasse sollten privat sein und keine geschützten Daten verwenden. Klassendesigner sollten niemals Dinge in eine öffentliche Schnittstelle einfügen, die von Benutzern der Klasse nicht benötigt werden.
(39) Theoretisch sollte die Vererbungshierarchie tiefer sein, je tiefer desto besser.
(40) In der Praxis sollte die Tiefe der Vererbungshierarchie die Kurzzeitgedächtniskapazität einer durchschnittlichen Person nicht überschreiten. Ein weithin akzeptierter Tiefenwert ist 6.
(41) Alle abstrakten Klassen sollten Basisklassen sein.
(42) Alle Basisklassen sollten abstrakte Klassen sein.
(43) Stellen Sie die Gemeinsamkeiten von Daten, Verhalten und/oder Schnittstellen in der Vererbungshierarchie so weit wie möglich ein.
(44) Wenn zwei oder mehr Klassen gemeinsame Daten teilen (aber kein gemeinsames Verhalten), dann sollten die gemeinsamen Daten in einer Klasse platziert werden, die in jeder Klasse enthalten ist, die diese Daten teilt.
(45) Wenn zwei oder mehr Klassen gemeinsame Daten und Verhaltensweisen (d. h. Methoden) haben, sollte jede dieser Klassen von einer gemeinsamen Basisklasse erben, die diese Daten und Methoden darstellt.
(46) Wenn zwei oder mehr Klassen eine gemeinsame Schnittstelle haben (die sich auf Nachrichten bezieht, nicht auf Methoden), sollten sie nur dann von einer gemeinsamen Basisklasse erben, wenn sie polymorph verwendet werden müssen.
(47) Eine Einzelfallanalyse der Darstellung von Objekttypen ist grundsätzlich falsch. In den meisten Fällen sollten Designer Polymorphismus verwenden.
(48) Eine Einzelfallanalyse der Anzeige von Attributwerten ist oft falsch. Klassen sollten in eine Vererbungshierarchie entkoppelt werden, wobei jeder Attributwert in eine abgeleitete Klasse umgewandelt wird.
(49) Modellieren Sie die dynamische Semantik einer Klasse nicht durch Vererbungsbeziehungen. Der Versuch, dynamische Semantik mit statischen semantischen Beziehungen zu modellieren, führt zur Laufzeit zu einem Typwechsel.
(50) Verwandeln Sie Klassenobjekte nicht in abgeleitete Klassen. Seien Sie vorsichtig bei abgeleiteten Klassen, die nur eine Instanz haben.
(51) Wenn Sie der Meinung sind, dass Sie zur Laufzeit eine neue Klasse erstellen müssen, treten Sie einen Schritt zurück und stellen Sie fest, dass Sie Objekte erstellen. Verallgemeinern Sie nun diese Objekte in einer Klasse.
(52) Es sollte illegal sein, eine leere Methode (d. h. eine Methode, die nichts tut) in einer abgeleiteten Klasse zu verwenden, um eine Methode in der Basisklasse zu überschreiben.
(53) Verwechseln Sie die optionale Einbeziehung nicht mit der Notwendigkeit einer Vererbung. Die Modellierung optionaler Inklusion als Vererbung führt zu einer Verbreitung von Klassen.
(54) Versuchen Sie beim Erstellen von Vererbungshierarchien, wiederverwendbare Frameworks anstelle wiederverwendbarer Komponenten zu erstellen.
(55) Wenn Sie in Ihrem Design Mehrfachvererbung verwenden, gehen Sie davon aus, dass Sie einen Fehler gemacht haben. Wenn Sie keinen Fehler gemacht haben, müssen Sie versuchen, ihn zu beweisen.
(56) Wenn Vererbung im objektorientierten Design verwendet wird, stellen Sie sich zwei Fragen: (1) Ist die abgeleitete Klasse ein spezieller Typ des Dings, das sie erbt? (2) Ist die Basisklasse Teil der abgeleiteten Klasse?
(57) Wenn Sie in einem objektorientierten Design Mehrfachvererbung finden, stellen Sie sicher, dass keine Basisklasse tatsächlich eine abgeleitete Klasse einer anderen Basisklasse ist.
(58) Wenn Sie beim objektorientierten Design zwischen Inklusion und Assoziation wählen müssen, wählen Sie bitte Inklusion.
(59) Verwenden Sie keine globalen Daten oder globalen Funktionen zur Buchhaltung von Objekten einer Klasse. Es sollten Klassenvariablen oder Klassenmethoden verwendet werden.
(60) Objektorientierte Designer sollten nicht zulassen, dass physikalische Designprinzipien ihre logischen Designs untergraben. Bei Entscheidungen über das logische Design greifen wir jedoch häufig auf physikalische Designkriterien zurück.
(61) Umgehen Sie nicht die öffentliche Schnittstelle, um den Status des Objekts zu ändern.