Per essere onesti, probabilmente prenderei un approccio completamente diverso. Costruivo 4 fabbriche, una per ogni tipo di oggetto. Creo quindi una nuova classe Level che contenga un'istanza di GunFactory e una di una GoalFactory e creerei 3 istanze di Level (probabilmente memorizzate in un elenco) ciascuna con la combinazione appropriata di factory.
Ci sono due ragioni per questo, una teorica e una pratica. A livello teorico, non è del tutto chiaro che le responsabilità "creare una pistola" e "creare un obiettivo" siano parte della stessa responsabilità, quindi il Modello di Responsabilità Unica afferma che dovremmo evitare di avere un singolo oggetto che lo fa. L'oggetto Livello ha invece una chiara responsabilità: "tenere insieme tutte le informazioni e il comportamento necessari per inizializzare un livello del gioco".
Il secondo aspetto, più pratico, è che ti consente di aggiungere nuovi livelli più facilmente di entrambi i tuoi suggerimenti originali. Di 'che vuoi aggiungere un quarto livello che usa di nuovo una combinazione diversa di pistola e obiettivo; nel tuo primo progetto dovresti cambiare il codice di inizializzazione esistente per scegliere un diverso set di fabbriche, nel secondo dovresti creare una nuova sottoclasse della tua classe factory astratta, mentre con il mio suggerimento devi semplicemente aggiungere un nuovo Livello di istanza alla lista, una singola linea cambia. (Questo potrebbe anche essere formulato teoricamente come "il design è più conforme al principio aperto / chiuso quando i livelli devono essere aggiunti", ma preferisco l'enfasi pratica qui).