2016-12-05 5 views
1

Ich habe zur Zeit einen asynchronen API, wo eine Klasse Manager Schaffung weiterer Objekte der Klasse verantwortlich ist A, B, C usw. Die Erstellung ist asynchron, und jeder Aufruf einer Funktion manager.createXXX() werde begleitet sein Rückruf on_createXXX_done(A& a).C++ Asynchronous Erstellung von Objekten

Die Erstellung der Objekte A, B, C muss sequenziell sein. Und eine typische Verwendung der API beinhaltet das Aufrufen der Erzeugung von A und in ihrem Rückruf das Auslösen der Erzeugung von B und so weiter.

Dies beinhaltet die Aufteilung der Erstellungslogik in viele Funktionen, die ich hässlich finde. Darüber hinaus müssen Operationen, die ausgeführt werden müssen, nachdem alle Objekte erstellt wurden, beim Rückruf des zuletzt erstellten Objekts (C) codiert werden, auch wenn keine direkte Beziehung zwischen diesem Objekt und der auszuführenden Operation besteht.

Builder Design-Muster passt nicht wirklich, da Manager nicht die Objekte A, B, C besitzt, es hilft nur bei der Erstellung und Rückgabe von ihnen.

void on_creationA_done(A& a) 
{ 
    m_a = a; 
    //Trigger next creation 
    m_manager.createB() 
} 
void on_creationB_done(B& b) 
{ 
    m_b = b; 
    //Trigger next creation 
    m_manager.createC() 
} 

void on_creationC_done(C& c) 
{ 
    m_c = c; 
    //No more creations are needed. Just perform some post-creation actions 
    do_something() // This needs to be called once all A, B, C are created. 
} 

Ich habe überprüft auch Torheit/Futures Kette asynchrone Operationen aber, dass beteiligt wäre Torheit Bibliothek durch unsere öffentliche API aussetzt, nicht wahr?

Was wäre ein gutes Muster in diesem Fall?

Antwort

0

Es scheint ein bisschen restriktiv (und nicht erweiterbar), die A, B, C Kreationen innerhalb ihrer Rückrufe zu verketten. Wenn in Zukunft mehr Anwendungsfälle implementiert werden müssen, müssen Sie diese auch innerhalb der Callbacks behandeln, was den Code zu komplex und nicht intuitiv macht.

Der aktuelle Fall ist ein spezieller Anwendungsfall, die mit Hilfe einer anderen Manager-Klasse behandelt werden sollen, machen sie es UseCaseABC nennen, die über den Anwendungsfalles des spezifischen Anforderungen kennen, Einschränkungen usw.

In UseCaseABC Klasse kann man Verfolgen Sie die Erstellung von A-, B- und C-Objekten und rufen Sie do_something auf, wenn alle drei Objekte existieren.

class UseCaseABC 
{ 

    void on_creationA_done(A& a) 
    { 
     m_A = a; 
     NotifyCreation(); 
    } 
    void on_creationB_done(B& b) 
    { 
     m_B = b; 
     NotifyCreation(); 
    } 
    void on_creationC_done(C& c) 
    { 
     m_C = c; 
     NotifyCreation(); 
    }  

    void NotifyCreation() 
    { 
     if (all three objects created) 
     { 
      do_something(); 

      ClearABCMembers(); 
     } 
    } 
} 

Wenn A, B, C Objekte Schaffung von vielen Clients asynchron ausgelöst wird, könnten Sie m_A, m_B, m_C Instanzen von Objektpools zugegriffen in einem Thread sichere Art und Weise ersetzen.

+0

Ich bin nicht ganz mit der Lösung einverstanden. Die Verwaltungsklasse kann mehr Objekte (oder weniger) erstellen. Nehmen wir an, Sie haben Objekte von A bis Z. Jeder Anwendungsfall oder jedes Szenario könnte die Erstellung einer beliebigen Teilmenge von Objekten anfordern. Das macht Ihre Lösung unmöglich, da Sie eine UseCase-Klasse pro Teilmenge erstellen müssen, also N Teilmengen (wobei N = pow (2, Anzahl der Objekte im Satz)) – FCR

+0

Es liegt an Ihnen zu entscheiden, ob Sie einen separaten Anwendungsfall erstellen müssen Klassen oder eine allgemeine, um alle Fälle zu behandeln. Und das hängt von der Komplexität jedes Anwendungsfalls und seiner Anzahl ab. – GeorgeT