Fabbrica astratta di costruttori di compositi - Iniezione delle dipendenze?

0

Speravo di ottenere un aiuto su una combinazione di modelli di progettazione complessi. Farò del mio meglio per semplificare il problema utilizzando esempi di base. La modularità è un bisogno molto grande in questo sistema, oltre all'estensibilità.

L'obiettivo è creare un elenco dinamico di oggetti compositi in base a un database. Modifica: Questo può essere visto come un requisito di un certo livello di riflessione. Semplificando in oggetti facilmente riconoscibili, diciamo che ci sono pulsanti e pannelli - materiali compositi che contengono un elenco di pulsanti. Ciascuno di questi oggetti è definito in una DLL separata per modularità ed estensibilità. In questo esempio, c'è una DLL Button e una DLL di Pannello che definiscono l'oggetto e i builder necessari per quell'oggetto da istanziare. Modifica: sono incluse anche le utilità di serializzazione e raccolta dati. L'oggetto che ha questi con un builder corrispondente aiuta a facilitare il riflesso richiesto.

Una fabbrica astratta centrale è usata per creare la versione più aggiornata di ogni oggetto trovato usando i costruttori. Supponiamo che, ad esempio, l'interfaccia client sia simile a questa (anche se nella versione finale tutte le stringhe hard-coded verranno sostituite con i dati del repository del database):

centralFactory.registerBuilder("Panel", panelBuilderInstance);
centralFactory.registerBuilder("Button", buttonBuilderInstance);
. . .
var newObject = centralFactory.create("Panel", "Central control panel");

In questo esempio, un costruttore che è stato registrato con l'identificativo "Panel" verrà in seguito utilizzato per creare un'entità e nominarlo "Pannello di controllo centrale" quando la fabbrica astratta viene istruita per creare un "Pannello".

Ora per la domanda! Poiché un pannello deve compilare un elenco di pulsanti da allegare come parte del modello di progettazione composito, il builder "Panel" dovrà sapere come utilizzare il builder "Button". Quale metodo risolve meglio questo problema?

Il mio istinto mi dice di usare l'iniezione di dipendenza e di passare la fabbrica astratta centrale ai costruttori quando si registrano i costruttori al loro identificatore di tipo. Tuttavia questo crea un po 'di brutta dipendenza circolare che spero di evitare. Modifica: la dipendenza circolare è che la fabbrica astratta dovrebbe conoscere IBuilder per registrarli, mentre l'istanza PanelBuilder dovrebbe specificamente conoscere la fabbrica astratta per creare pulsanti. Suppongo che non sia una dipendenza circolare VERA poiché deve passare attraverso uno strato di ereditarietà, ma le dipendenze preferibilmente sono unidirezionali quando possibile. Ad esempio.

AbstractFactory::registerBuilder(string identifier, IBuilder builder)
{
    builderList.add(identifier, builder);
}
IBaseObject AbstractFactory::create(string identifier, string name)
{
    var newObject = builderList[identifier].create(this);
    newObject.Name = name;
    return newObject;
}
. . .
IBaseObject PanelBuilder::create(AbstractFactory centralFactory)
{
    newObject = new Panel;
    newObject.add(centralFactory.create("Button", "Play"));
    newObject.add(centralFactory.create("Button", "Pause"));
    newObject.add(centralFactory.create("Button", "Stop"));
    newObject.add(centralFactory.create("Button", "Rewind"));
    newObject.add(centralFactory.create("Button", "Fast Forward"));
    return newObject;
}

Modifica: l'iniezione delle dipendenze vorrebbe questo, con l'aggregazione inferiore tra AbstractComponentFactory e CompositeComponentFactory che rappresenta l'iniezione:

Modifica: in questo esempio il pulsante deriverebbe da Componente e il pannello deriverebbe da CompositeComponent. In UML, non ho nominato nulla come Builder perché in realtà questa implementazione si riduce leggermente tra Factory e Builder a seconda del ruolo del contesto. Ad esempio, la costruzione di un pulsante funziona come una fabbrica, tuttavia durante la costruzione del pannello, AbstractFactory si comporta più come un costruttore in cui la fabbrica madre passa a un direttore. Per semplicità e utilizzo non è stato necessario utilizzare questi termini completamente testualmente.

Esiste un metodo migliore per evitare l'iniezione delle dipendenze in cui i miei builder devono essere a conoscenza del mio controllo centrale di fabbrica per produrre veramente un oggetto composito?

L'unica alternativa che posso vedere è che l'oggetto Panel ha una conoscenza completa dell'oggetto Button, che potrebbe essere problematico per la modularità.

NOTA: il codice precedente non è pensato per un particolare linguaggio o stile, quindi tieni le critiche sulla sintassi e la formattazione al minimo. Inoltre, il controllo degli errori è stato saltato per motivi di pseudo-codice.

    
posta Gren Meera 08.05.2018 - 18:02
fonte

0 risposte