Design Pattern per un tipo di "manager" di classe

0

Ho una classe che di solito finisco per chiamare XManager . Questa classe di solito agisce come un dispatcher. Dove leggerà una configurazione e farà ciò che dice la configurazione.

Supponendo che abbia la seguente struttura di classe:

-Manger
 | - Phases
   | - PhaseX implements Phase { void run(); }
   | - PhaseY implements Phase { void run(); }
   | - PhaseZ implements Phase { void run(); }
 PhaseManager

In PhaseManager ho un codice che assomiglia a:

class PhaseManager {
    private Set<Phase> phases;

    public PhaseManager(Config config) {
        // Use config to instantiate all enabled phases, adding them to phases.
    }

    public void runPhases() {
        for(Phase p : phases) {
            p.run();
        }
    }
}

E quindi nel mio main.java avrei qualcosa del tipo:

PhaseManager manager = new PhaseManager(config);
manager.runPhases();

Ma sono convinto che ci sia un modo migliore. E dopo aver letto molti degli schemi di progettazione non riesco a capire esattamente a quale modello di design si adatti meglio.

Sembra che potrebbe essere callback , ma non proprio; poiché non vi è alcuna azione che si verifichi per avviarlo, deve solo succedere.

Potrebbe essere command , ma sembra che il comando sia un po 'eccessivo per questo approccio.

    
posta lilott8 28.07.2017 - 21:26
fonte

2 risposte

1

Penso che lo stesso può (e probabilmente dovrebbe) essere espresso più pulito usando il modello di builder.

Result result = InitialPhase.fromConfig(config)
                            .phase1(...)
                            .phase2(...)
                            // ...
                            .build();

Ogni metodo .phaseN() può restituire una classe che consente solo di richiamare le fasi successive corrette. (Nel progetto "PhaseManager" è possibile eseguire le fasi in ordine arbitrario.) Ogni .phaseN(...) può accettare qualsiasi parametro specifico della fase che può esserci.

L'ultimo .build() rende l'oggetto risultante da un oggetto fase. Se l'area tematica lo consente, diverse fasi possono fornire un metodo .build() , consentendo percorsi di compilazione diversi.

    
risposta data 29.07.2017 - 05:09
fonte
3

Non ho abbastanza reputazione per commentare, quindi cerchiamo una risposta.

La tua classe viola il SRP perché: 1. usa la configurazione per istanziare tutte le fasi abilitate, 2. esegui le fasi.

Preferirei qualcosa di simile a:

class PhasesCreator {
    List<Phase> createPhases(Config config) { ... }
}

Nel tuo main, esegui le tue fasi in questo modo:

for(Phase p : phases) {
        p.run();
}

O con lo stile Java 8:

phases.forEach(Phase::run);

Puoi anche racchiudere l'esecuzione delle fasi in una classe dedicata, ad esempio una classe PhasesRunner :

class PhasesRunner {
     void run(Iterable<Phase> phases) { ... }
}

Modifica Per riassumere:

  • Hai bisogno di un schema creativo (fabbrica, fabbrica astratta, costruttore, ...) per creare un'istanza la raccolta delle fasi;
  • Potrebbe essere necessario o meno un modello specifico (ad es. comando) per eseguire le fasi, ma non ho abbastanza informazioni per esprimere un'opinione.

A parte la domanda originale:

Sembra che tu stia scrivendo un compilatore. Non vedo il flusso di dati da testo a binario (caratteri, token, ...) nel disegno corrente. Dovresti, almeno, applicare l'ordine delle fasi utilizzando un tipo di input e un tipo di ritorno per il metodo run :

interface Phase<I, O> {
    O run(I input);
}

Ma l'esecuzione delle fasi non sarà più solo un ciclo.

    
risposta data 28.07.2017 - 22:51
fonte

Leggi altre domande sui tag