Aiuta a eliminare la dipendenza circolare

1

Ho la seguente dipendenza circolare che vorrei eliminare. Penso di avere un difetto nel mio design. E apprezzerei molto qualsiasi feedback su come risolvere questo problema.

La mia dipendenza circolare proviene da 3 classi importanti. Worker , WorkingContext e TaskManager .

Per prima cosa, ho classi di 2 Worker ( Worker e WorkerGroup ). Ogni Worker viene creato con un oggetto WorkingContext che memorizza informazioni sullo stato.

class Worker 
{
    Worker(WorkingContext * context);
};

class WorkerGroup
{
};

Successivamente, ho WorkingContext .

class WorkingContext
{
    // state info and various getters
    ...
    TaskManager * getTaskManager();
};

Come mostrato, una delle cose che WorkingContext memorizza è una TaskManager , che ha un numero di funzioni utili che dipendono da Worker . Ecco uno snippet

class TaskManager
{
    void assignCredit(Worker * worker, WorkerGroup * group, int credit);
    void revokeCredit(Worker * worker, int credit);
};

La dipendenza circolare è che Worker.h ha bisogno di #include "WorkingContext.h" , che ha bisogno di #include "TaskManager.h" , che a sua volta ha bisogno di #include "Worker.h" .

In questo momento funziona perché sto usando il riferimento futuro, ma questa è davvero l'ultima risorsa.

    
posta user3240688 16.08.2016 - 20:48
fonte

2 risposte

1

Se Task Manager non contiene lo stato, puoi estrarlo dal contesto di lavoro e renderne statiche tutte le funzioni.

Altrimenti, considerando quanto poco so dal frammento, posso solo immaginare quale sarà un buon progetto, ma mi sembra che un lavoratore non dovrebbe contenere (indirettamente) un task manager.

Se il progetto è tale per cui ogni lavoratore ha un oggetto contesto statico specifico, questo oggetto non è il contenitore giusto per un'API del task manager, specialmente perché sembra che il task manager usi un lavoratore e non il altro modo.

Prova ad esprimere le dipendenze logiche usando le relazioni "Ha un" e "Usa un" per determinare meglio una gerarchia appropriata. Nota che "Utilizza un" non implica necessariamente il contenimento o la proprietà.

    
risposta data 17.08.2016 - 00:21
fonte
1

Questo design sembra corretto. Nella vita reale ci sono molte dipendenze reciproche come questa.

Come ha sottolineato Sebastian nei commenti, le dichiarazioni anticipate delle classi non sono un lavoro da svolgere. Sono semplicemente necessari in caso di dipendenze reciproche. L'unica cosa che cambierei sarebbe usare puntatori intelligenti invece di puntatori grezzi.

Potresti tuttavia rendere il design più robusto utilizzando il schema del mediatore per fungere da una sorta di hub tra gli oggetti e incapsulare le interazioni tra le diverse parti della collaborazione (vedi qui la checklist e qui un esempio ). La conseguenza sarebbe che Worker , Workgroup e TaskManager non interagirebbero direttamente; ciascuno interagirebbe solo con il mediatore. Intuitivamente, il tuo WorkingContext potrebbe essere un buon inizio per il mediatore concreto.

    
risposta data 20.08.2016 - 02:17
fonte