Das Prinzip des geringsten Wissens oder das Gesetz von Demeter ist eine Warnung davor, Ihre Klasse mit Details anderer Klassen zu verwickeln, die Schicht für Schicht durchlaufen. Es sagt Ihnen, dass es besser ist, nur mit Ihren "Freunden" und nicht mit "Freunden von Freunden" zu sprechen.
Stellen Sie sich vor, Sie wurden gebeten, einen Schild an eine Statue eines Ritters in glänzender Plattenrüstung zu schweißen. Sie positionieren den Schild vorsichtig auf dem linken Arm, damit er natürlich aussieht. Sie bemerken, dass es drei kleine Stellen am Unterarm, am Ellbogen und am Oberarm gibt, an denen der Schild zufällig die Rüstung berührt. Sie schweißen alle drei Stellen, weil Sie sicherstellen möchten, dass die Verbindung fest ist. Stellen Sie sich vor, Ihr Chef ist verrückt, weil er den Ellbogen seiner Rüstung nicht bewegen kann. Sie nahmen an, dass sich die Rüstung niemals bewegen würde, und stellten so eine unbewegliche Verbindung zwischen Unterarm und Oberarm her. Der Schild sollte sich nur mit seinem Freund, dem Unterarm, verbinden. Nicht zu Unterarmfreunden. Auch wenn Sie ein Stück Metall hinzufügen müssen, damit sie sich berühren.
Metaphern sind nett, aber was meinen wir eigentlich mit Freund? Alles, was ein Objekt zu erstellen oder zu finden weiß, ist ein Freund. Alternativ kann ein Objekt nur verlangen, dass ihm andere Objekte übergeben werden , von denen es nur die Schnittstelle kennt. Diese zählen nicht als Freunde, da keine Erwartung auferlegt wird, wie man sie bekommt. Wenn das Objekt nicht weiß, woher es kommt, weil etwas anderes es passiert / injiziert hat, dann ist es kein Freund eines Freundes, es ist nicht einmal ein Freund. Es ist etwas, das das Objekt nur zu verwenden weiß. Das ist gut.
Wenn Sie versuchen, Prinzipien wie diese anzuwenden, ist es wichtig zu verstehen, dass sie Sie niemals daran hindern, etwas zu erreichen. Dies ist eine Warnung, dass Sie möglicherweise nicht mehr daran arbeiten, um ein besseres Design zu erzielen, das dasselbe erreicht.
Niemand möchte ohne Grund arbeiten, daher ist es wichtig zu verstehen, was Sie daraus machen. In diesem Fall bleibt Ihr Code flexibel. Sie können Änderungen vornehmen und weniger andere Klassen von den Änderungen beeinflussen lassen, um die Sie sich Sorgen machen müssen. Das hört sich gut an, hilft Ihnen aber nicht bei der Entscheidung, was Sie tun sollen, es sei denn, Sie betrachten es als eine Art religiöse Lehre.
Anstatt dieses Prinzip blind zu befolgen, nehmen Sie eine einfache Version dieses Problems. Schreiben Sie eine Lösung, die nicht dem Prinzip folgt, und eine, die es tut. Jetzt, da Sie zwei Lösungen haben, können Sie vergleichen, wie empfänglich jede für Änderungen ist, indem Sie versuchen, sie in beiden umzusetzen.
Wenn Sie ein Problem nicht lösen können, während Sie diesem Prinzip folgen, fehlt Ihnen wahrscheinlich eine weitere Fähigkeit.
Eine Lösung für Ihr spezielles Problem besteht darin, das frame
in etwas (eine Klasse oder Methode) einzufügen, das weiß, wie mit Frames gesprochen wird, damit Sie nicht all diese Frame-Chat-Details in Ihrer Klasse verbreiten müssen, die jetzt nur wissen, wie und wann einen Rahmen bekommen.
Das folgt eigentlich einem anderen Prinzip: Getrennte Nutzung von Konstruktion.
frame = encoder->WaitEncoderFrame()
Indem Sie diesen Code verwenden, haben Sie die Verantwortung dafür übernommen, auf irgendeine Weise eine zu erwerben Frame
. Sie haben noch keine Verantwortung für das Gespräch mit a übernommen Frame
.
frame->DoOrGetSomething();
Jetzt musst du wissen, wie man mit a spricht Frame
, aber ersetze das durch:
new FrameHandler(frame)->DoOrGetSomething();
Und jetzt müssen Sie nur noch wissen, wie Sie mit Ihrem Freund FrameHandler sprechen können.
Es gibt viele Möglichkeiten, dies zu erreichen, und dies ist vielleicht nicht die beste, aber es zeigt, wie die Befolgung des Prinzips das Problem nicht unlösbar macht. Es fordert nur mehr Arbeit von dir.
Jede gute Regel hat eine Ausnahme. Die besten Beispiele, die ich kenne, sind interne domänenspezifische Sprachen . Eine DSL s Methodenkettescheint das Gesetz von Demeter ständig zu missbrauchen, weil Sie ständig Methoden aufrufen, die verschiedene Typen zurückgeben, und diese direkt verwenden. Warum ist das in Ordnung? Denn bei einem DSL ist alles, was zurückgegeben wird, ein sorgfältig entworfener Freund, mit dem Sie direkt sprechen sollen. Sie haben das Recht, von der Methodenkette eines DSL zu erwarten, dass sie sich nicht ändert. Sie haben dieses Recht nicht, wenn Sie sich nur zufällig mit der Verkettung der Codebasis befassen, was auch immer Sie finden. Die besten DSLs sind sehr dünne Darstellungen oder Schnittstellen zu anderen Objekten, auf die Sie wahrscheinlich auch nicht eingehen sollten. Ich erwähne dies nur, weil ich das Gesetz der Demeter viel besser verstanden habe, als ich erfuhr, warum DSLs ein gutes Design sind. Einige gehen sogar so weit zu behaupten, dass DSLs nicht einmal gegen das wahre Gesetz von Demeter verstoßen.
Eine andere Lösung besteht darin, etwas anderes frame
in dich spritzen zu lassen. Wenn Sie frame
von einem Setter oder vorzugsweise einem Konstrukteur kommen, übernehmen Sie keine Verantwortung für die Konstruktion oder den Erwerb eines Rahmens. Das bedeutet, dass deine Rolle hier viel mehr so ist, wie FrameHandlers
sie sein würde. Stattdessen sind Sie jetzt derjenige, der mit Frame
etwas anderem plaudert und herausfindet, wie man eine Frame
In gewisser Weise gleiche Lösung mit einem einfachen Perspektivenwechsel erhält .
Die SOLID- Prinzipien sind die großen, denen ich zu folgen versuche. Zwei davon sind die Prinzipien der Einzelverantwortung und der Abhängigkeitsumkehr. Es ist wirklich schwer, diese beiden zu respektieren und trotzdem das Gesetz von Demeter zu verletzen.
Die Mentalität, mit der Demeter verletzt wird, ist so, als würde man in einem Buffetrestaurant essen, in dem man sich einfach schnappt, was man will. Mit ein wenig Vorarbeit können Sie sich selbst ein Menü und einen Server zur Verfügung stellen, der Ihnen alles bringt, was Sie möchten. Lehnen Sie sich zurück, entspannen Sie sich und geben Sie ein gutes Trinkgeld.