Ich habe dieses generelle Problem beim Design, Refactoring oder "Triage":
Ich habe eine bestehende Multithreading-C++-Anwendung, die für Daten mit einer Reihe von Plugin-Bibliotheken sucht. Mit der aktuellen Suchschnittstelle erhält ein bestimmtes Plugin einen Suchstring und einen Zeiger auf ein QList-Objekt. Das Plugin läuft auf einem anderen Thread und durchsucht verschiedene Datenquellen (lokal und im Internet) und fügt die gewünschten Objekte der Liste hinzu. Wenn das Plugin zurückkehrt, fügt das Hauptprogramm, das sich immer noch auf dem separaten Thread befindet, diese Daten in den lokalen Datenspeicher ein (mit weiterer Verarbeitung), wobei dieser Einfügepunkt durch einen Mutex geschützt wird. So kann jedes Plugin Daten asynchron zurückgeben.
Die QT-base Plugin-Bibliothek basiert auf Message Passing. Es gibt eine ganze Reihe von Plugins, die bereits für die Anwendung geschrieben und getestet wurden, und sie funktionieren recht gut.
Ich möchte einige weitere Plugins schreiben und die bestehende Anwendung nutzen.
Das Problem ist, dass die neuen Plugins mehr Informationen von der Anwendung benötigen. Sie müssen bei ihrer Suche zeitweise auf den lokalen Datenspeicher selbst zugreifen. Um diesen zu erhalten, bräuchten sie also direkten oder indirekten Zugriff sowohl auf das Hash-Array, in dem die Daten gespeichert sind, als auch auf den Mutex, der den Mehrfachzugriff auf den Speicher überwacht. Ich nehme an, dass der Zugriff durch Hinzufügen einer zusätzlichen Methode in einem "Katalog"-Objekt gekapselt werden würde.
Ich sehe drei Möglichkeiten, diese neuen Plugins zu schreiben.
-
Wenn Sie ein Plugin laden, übergeben Sie ihnen einen Zeiger auf meinen "Katalog" an die Start. Dies wird eine zusätzliche, "unsichtbare" Schnittstelle für die neuen Plugins. Dies scheint schnell, einfach, völlig falsch im Sinne von OO, aber Ich kann nicht erkennen, wo die zukünftigen Probleme liegen könnten.
-
Hinzufügen einer Methode/Nachricht zur bestehende Schnittstelle, damit ich eine zweite Funktion, die sein könnte für die neue Plugin-Bibliothek aufgerufen werden kann
-
Umgestaltung der Plugin-Schnittstelle. Dies scheint laut OO "das Beste" zu sein, könnte andere zusätzliche Vorteile haben, aber würde alle Arten von umschreiben.
Meine Fragen lauten also
A. C konkrete Gefährdungen der Option 1?
B. Gibt es ein bekanntes Muster, das auf diese Art von Problem passt?
Bearbeiten1:
Eine typische Funktion zum Aufruf der Plugin-Routinen sieht so aus:
elsewhere(spec){
QList<CatItem> results;
plugins->getResult(spec, &results);
use_list(results);
}
...
void PluginHandler::getResults(QString* spec, QList<CatItem>* results)
{
if (id->count() == 0) return;
foreach(PluginInfo info, plugins) {
if (info.loaded)
info.obj->msg(MSG_GET_RESULTS, (void*) spec, (void*) results);
}
}
Das zieht sich wie ein roter Faden durch den Code. Ich würde ihn lieber erweitern, als ihn zu zerstören.