Wie kann ich eine Abhängigkeitsdeklaration für einen Freund richtig entfernen / umgestalten?
Der Hintergrund dieser Frage basiert auf einem praktischen Beispiel, in dem ich die Abhängigkeit eines Freundes von zwei Klassen entfernen wollte, die zum Verwalten des gesperrten Lese- / Schreibzugriffs auf eine freigegebene Ressource verwendet werden.
Hier ist eine Abstraktion des ursprünglichen strukturellen Entwurfs für dieses Szenario:
Markiert in Rot, gibt es diese hässliche Abhängigkeit von einem Freund, die ich aus dem Design entfernen möchte.
urz gesagt, warum habe ich dieses Ding dort:
ClassAProvider
teilt einen Verweis auf einClassA
über eine Reihe von gleichzeitigem Zugriff aufClient
instanceClient
Instanzen sollten auf @ zugreifClassA
nur durch dasClassAAccessor
Helferklasse, die die Interna verwaltetClassA
verbirgt alle Methoden, die verwendet werden sollen, vorClassAAccessor
als geschützt.SoClassA
kann sicherstellen, dassClient
muss ein @ verwendClassAAccessor
instanceDieses Muster ist in erster Linie nützlich, wenn sichergestellt werden soll, dass Instanzen von @ verlassen werdeClassA
in einem definierten Zustand, wenn einClient
ie @ -Operation wird beendet (z. B. aufgrund einer nicht erfassten Ausnahme). Denk anClassA
Bereitstellung von (intern sichtbaren) gepaarten Operationen wielock()
/unlock()
oderopen()
/close()
.
Die (Status-) Umkehroperationen sollten auf jeden Fall aufgerufen werden, insbesondere wenn ein Client aufgrund einer Ausnahme abstürzt.
Dies kann sicher über das @ gehandhabt werdClassAAcessor
as Lebenszyklusverhalten von @ kann durch die Destruktor-Implementierung sichergestellt werden. Das folgende Sequenzdiagramm veranschaulicht das beabsichtigte Verhalten:
ZusätzlichClient
Instanzen können eine genaue Kontrolle über den Zugriff auf @ erreicheClassA
einfach mit C ++ - Scope-Blöcken:
// ...
{
ClassAAccessor acc(provider.getClassA());
acc.lock();
// do something exception prone ...
} // safely unlock() ClassA
// ...
Alles in Ordnung so weit, aber die «Freund» Abhängigkeit zwischenClassA
undClassAAccessor
sollte aus mehreren guten Gründen entfernt werden
The following table lists predefined standard elements for UML 1.x that are now obsolete. ... «friend» ...
Die meisten Codierungsregeln und -richtlinien, die ich gesehen habe, raten davon ab, friend zu verwenden, um die enge Abhängigkeit von den exportierenden Klassen zu den Freunden zu vermeiden. Diese Sache bringt einige ernsthafte Wartungsprobleme mit sich.Wie mein Fragentitel sagt
Wie kann ich eine Friend-Deklaration korrekt entfernen / umgestalten (am besten mit dem UML-Design für meine Klassen beginnen)?