Ich bin mir nicht sicher, ob es sich um eine Frage zur Programmierungstechnik oder zum Design handelt, aber ich bin für Vorschläge offen.
Das Problem: Ich möchte eine Abstraktionsschicht zwischen Datenquellen (Sensoren) und Verbrauchern erstellen. Die Idee ist, dass die Verbraucher nur die Schnittstellen (abstrakte Basisklasse) verschiedener Sensortypen "kennen". Jeder dieser Sensortypen besteht in der Regel aus mehreren individuellen Werten, von denen jeder seine eigenen Getter-Methoden hat.
Als Beispiel verwende ich einen vereinfachten GPS-Sensor.
class IGpsSensor {
public:
virtual float getLongitude() = 0;
virtual float getLatitude() = 0;
virtual float getElevation() = 0;
// Abweichungen
virtual float getLongitudeDev() = 0;
virtual float getLatitudeDev() = 0;
virtual float getElevationDev() = 0;
virtual int getNumOfSatellites() = 0;
};
Da Aktualisierungen des Sensors von einem anderen Thread durchgeführt werden (die Details obliegen der Implementierung der Schnittstelle), erscheint es vernünftig, Getter und auch die Aktualisierungsmethoden zu synchronisieren, um Konsistenz sicherzustellen.
Bisher so gut. In den meisten Fällen sollte diese Ebene der Synchronisierung ausreichen. Manchmal kann es jedoch notwendig sein, mehr als einen Wert zu erfassen (mit aufeinanderfolgenden getXXX()-Aufrufen) und sicherzustellen, dass keine Aktualisierung dazwischengeschoben wird. Ob dies erforderlich ist oder nicht (und welche Werte wichtig sind), liegt am Verbraucher.
Wenn wir beim Beispiel bleiben, ist es in vielen Fällen nur wichtig, Längen- und Breitengrad zu kennen (hoffentlich aber beide auf dasselbe update() bezogen). Ich gebe zu, dass dies durch Gruppierung in eine "Position" Klasse oder Struktur erreicht werden könnte. Aber ein Verbraucher könnte den Sensor auch für einen komplizierteren Algorithmus verwenden und benötigt damit auch die Abweichung.
Jetzt frage ich mich, was der richtige Weg wäre, dies zu tun.
Die Lösungen, an die ich dachte:
-
Alle möglichen Werte in eine Struktur (oder Klasse) gruppieren und eine zusätzliche (synchronisierte) Getter-Methode hinzufügen, die Kopien aller Werte auf einmal zurückgibt - scheint mir in Fällen, in denen nur 2 oder 3 von vielleicht 10 Werten benötigt werden, wie eine Menge unnötiger Overhead.
-
Eine Methode hinzufügen, die eine Referenz auf den im Datenquellen verwendeten Mutex zurückgibt, um das Sperren durch den Verbraucher zu ermöglichen - das fühlt sich nicht nach "gutem Design" an. Und da die Getter bereits synchronisiert sind, ist die Verwendung eines rekursiven Mutex obligatorisch. Ich gehe jedoch davon aus, dass es mehrere Leser, aber nur einen Schreiber gibt, und ich würde daher eher ein Shared Mutex verwenden.
Danke für Ihre Hilfe.