Quando il codice cliente può conoscere le implementazioni del modello di strategia?

5

Sto pensando di utilizzare un modello di strategia per la gestione dei file di configurazione, in questo modo posso supportare alcune configurazioni legacy. Mi sento abbastanza solido sul design generale (come il suo modello di strategia piuttosto standard), ma sono curioso di sapere se il client deve conoscere il tipo di strategia che viene implementata o se viola il modello di strategia. In particolare, il costruttore di ConfigurationParser richiede un istream e una stringa (o forse enum) del tipo di flusso che è (xml, json, ini, ecc.) Per sapere quale strategia concreta istanziare.

Idealmente mi piacerebbe solo passare l'istream, ma se lo faccio allora probabilmente dovrò inserire il codice nel ConfigurationParser per discernere il tipo di stream cercando parentesi angolari o parentesi quadre o qualcosa del genere.

Ho deciso di non passare un percorso di file di stringhe e di determinare il tipo dall'estensione perché la roba legacy non è sempre coerente nella denominazione dell'estensione e rende il mio codice molto più semplice da testare se passo flussi invece di percorsi di file codificati.

    
posta ÁEDÁN 10.07.2017 - 17:44
fonte

1 risposta

4

Mi sembra che tu abbia due problemi diversi. Il problema A è facile da risolvere. Ma il problema B è più difficile.

Il problema A è di chiamare dinamicamente una determinata strategia dato un configString. Che può essere risolto creando una mappa e associando un'istanza di ogni parser con una stringa che la identifica. In questo modo recuperi dalla mappa il parser di cui hai bisogno. Se il parser è troppo costoso da istanziare, puoi invece inserire nella mappa un builder per quel parser. Questa soluzione presuppone che l'utente finale (o tu) sappia quale tipo di file di configurazione verrà analizzato.

Ovviamente, per ottenere il disaccoppiamento totale, una fabbrica dovrebbe impostare l'intera mappa dei parser (o del parser builder) e il client dovrebbe avere questa mappa passata ad essa. In questo modo solo la fabbrica è strettamente collegata ai parser di cemento.

Il problema B è che vuoi determinare automaticamente quale tipo di file (o istream) stai leggendo per utilizzare il parser appropriato , cioè l'utente finale (o tu) non selezionerà il file e dire all'app il tipo di file conf.

Una soluzione per il problema B è quella di avere tutti i parser in una lista e iterare attraverso di essa. Quando un parser non riesce ad analizzare il flusso, vai al parser successivo e così via. Se un parser analizza correttamente il flusso, fine della trama (puoi riportare quale parser hai usato definitivamente se aggiungi un campo nome al parser). Se ogni parser non riesce, il file non è supportato da alcun parser. Non è necessario investigare all'interno del flusso per indovinare il formato, lasciare che i parser cerchino di analizzarlo. Un potenziale problema che vedo con questa soluzione è che è possibile che due diversi parser possano interpretare lo stesso formato di input in modi diversi senza fallire. In tal caso, il primo parser che fa farà sempre il lavoro e potrebbe non essere quello che ti aspettavi.

Un risultato del log potrebbe essere simile a questo:

Parsing: unknown_config_file
..not XML
..not JSON
..successfully parsed using "ini" parser.

o

Parsing: unknown_config_file
..not XML
..not JSON
..not ini
..unsuported config file.
    
risposta data 10.07.2017 - 20:23
fonte