Denken Sie an Martins Stabilitätsmetrik und was er unter "Stabilität" versteht:
Instability = Ce / (Ca+Ce)
Oder:
Instability = Outgoing / (Incoming+Outgoing)
Das heißt, ein Paket wird als völlig instabil betrachtet, wenn alle seine Abhängigkeiten ausgehen: Es verwendet andere Dinge, aber nichts verwendet es. In diesem Fall ist es nur sinnvoll, dass das Ding konkret ist. Es wird auch die am einfachsten zu ändernde Art von Code sein, da nichts anderes ihn verwendet und daher nichts anderes kaputt gehen kann, wenn dieser Code geändert wird.
Wenn Sie in der Zwischenzeit das gegenteilige Szenario einer vollständigen "Stabilität" mit einem Paket haben, das von einem oder mehreren Dingen verwendet wird, aber nichts für sich allein verwendet, wie ein zentrales Paket, das von der Software verwendet wird, dann sagt Martin, dass dies der Fall sein sollte abstrakt. Dies wird auch durch den DIP-Teil von SOLI (D), das Prinzip der Abhängigkeitsinversion, verstärkt, der im Wesentlichen besagt, dass Abhängigkeiten für Code auf niedriger und hoher Ebene einheitlich in Richtung Abstraktionen fließen sollten.
Das heißt, Abhängigkeiten sollten einheitlich in Richtung "Stabilität" fließen, und genauer gesagt, Abhängigkeiten sollten in Richtung von Paketen mit mehr eingehenden Abhängigkeiten als ausgehenden Abhängigkeiten fließen, und außerdem sollten Abhängigkeiten in Richtung Abstraktionen fließen. Der Grundgedanke dahinter ist, dass Abstraktionen Raum zum Atmen bieten, um einen Subtyp durch einen anderen zu ersetzen, und den konkreten Teilen, die die Schnittstelle implementieren, diesen Grad an Flexibilität bieten, um sich zu ändern, ohne die eingehenden Abhängigkeiten von dieser abstrakten Schnittstelle zu zerstören.
Gibt es signifikante Nachteile bei der Abhängigkeit von Abstraktionen?
Nun, ich stimme Martin hier zumindest für meine Domain nicht zu, und hier muss ich eine neue Definition von "Stabilität" einführen, wie in "Fehlende Gründe für eine Änderung". In diesem Fall würde ich sagen, Abhängigkeiten sollten in Richtung Stabilität fließen, aber abstrakte Schnittstellen helfen nicht, wenn abstrakte Schnittstellen instabil sind (nach meiner Definition von "instabil", da sie dazu neigen, wiederholt geändert zu werden, nicht Martins). Wenn die Entwickler die Abstraktionen nicht korrigieren können und Clients ihre Meinung wiederholt so ändern, dass abstrakte Versuche, die Software zu modellieren, unvollständig oder ineffektiv sind, profitieren wir nicht mehr von der erweiterten Flexibilität abstrakter Schnittstellen, um das System vor kaskadierenden Änderungen zu schützen, die die Abhängigkeit aufheben . In meinem persönlichen Fall habe ich ECS-Engines gefunden, wie sie in AAA-Spielen zu finden sind.am konkretesten : in Richtung Rohdaten, aber solche Daten sind sehr stabil (wie in "Es ist unwahrscheinlich, dass sie jemals geändert werden müssen"). Ich habe oft festgestellt, dass die Wahrscheinlichkeit, dass zukünftige Änderungen erforderlich sind, eine nützlichere Messgröße ist als das Verhältnis von efferenten zu Gesamtkopplungen bei der Steuerung von SE-Entscheidungen.
Daher würde ich DIP ein wenig ändern und einfach sagen: "Abhängigkeiten sollten zu Komponenten fließen, bei denen die geringste Wahrscheinlichkeit besteht, dass weitere Änderungen erforderlich sind", unabhängig davon, ob es sich bei diesen Komponenten um abstrakte Schnittstellen oder Rohdaten handelt. Für mich ist nur die Wahrscheinlichkeit von Bedeutung, dass direkte Änderungen erforderlich sind. Abstraktionen sind in diesem Kontext der Stabilität nur dann nützlich, wenn etwas, indem es abstrakt ist, diese Wahrscheinlichkeit verringert.
In vielen Kontexten kann dies bei anständigen Ingenieuren und Kunden der Fall sein, die die Anforderungen der Software im Voraus antizipieren und stabile (wie in unveränderlichen) Abstraktionen entwerfen, während diese Abstraktionen ihnen den nötigen Freiraum bieten, um konkrete Implementierungen auszutauschen. In einigen Bereichen sind die Abstraktionen jedoch möglicherweise instabil und können unzureichend sein, während die für die Engine erforderlichen Daten möglicherweise viel einfacher vorherzusehen und im Voraus stabil zu machen sind. In diesen Fällen kann es unter dem Gesichtspunkt der Wartbarkeit (der einfachen Änderung und Erweiterung des Systems) tatsächlich vorteilhafter sein, dass Abhängigkeiten eher zu Daten als zu Abstraktionen fließen. In einem ECS sind die instabilsten Teile (wie bei Teilen, die am häufigsten geändert werden) normalerweise die Funktionen, die sich in Systemen befinden (PhysicsSystem
z. B.), während die stabilsten Teile (die am wenigsten wahrscheinlich geändert werden) die Komponenten sind, die nur aus Rohdaten ( MotionComponent
z. B.) bestehen, die alle Systeme verwenden.