In questa sezione segue una descrizione più dettagliata della struttura del nostro sistema e dei pattern utilizzati.
Come detto precedentemente, la scelta rilevante del progetto è relativa all’uso del pattern MVC. Questa decisione ci ha permesso di tenere separata la logica dalla grafica, rendendo così il codice facilmente modificabile ed estendibile nel futuro. Inoltre, il progetto prevede un’architettura modulare dove ogni funzionalità del sistema è racchiusa in un modulo. Infine, il controller rappresenta il punto centrale del progetto in quanto incapsula lo stato attuale del gioco, andando così a garantire coerenza tra le diverse viste.
In questa sotto sezione vengono spiegati i pattern utilizzati nei componenti dell’MVC.
Per lo sviluppo delle logiche dei mini-giochi è stato usato il pattern Strategy. Infatti, tutti i mini-giochi aderiscono al contratto MiniGameLogic e poi, ognuno di loro, implementerà i propri metodi in base alle regole del mini-gioco. Le funzioni fondamentali di ogni mini-gioco sono:
La view si occupa di gestire i pannelli di gioco e di mostrare i risultati in base alla modalità di gioco scelta. All’interno della view abbiamo utilizzato i seguenti pattern:
All’avvio viene mostrato il menù principale (MenuView.scala) che permette di scegliere una delle modalità di gioco tra Age Test e Brain Training oppure di consultare le regole del gioco.
AgeTest.scala e BrainTraining.scala sono le classi che rappresentano le due modalità di gioco:
Entrambe le classi, creano i pannelli dei mini giochi e dei risultati utilizzando le rispettive factory GamePanelsFactory e ResultPanelsFactory. Lo scopo principale di queste factory è creare e restituire pannelli già configurati e pronti all’uso. Inoltre AgeTest.scala e BrainTraining.scala contengono anche metodi che si occupano di reagire a eventi come onGameFinished e onGameChanged, implementando quindi il pattern Observer.
Ciascun mini gioco dispone di un panel dedicato, che estende il trait SimpleQuestionAnswerGamePanel.scala: in questo caso è stato adottato il pattern Template Method, poiché il trait definisce il comportamento comune a tutti i pannelli, consentendo alle sottoclassi di ridefinire o personalizzare solo le parti necessarie, evitando duplicazioni di codice.
Infine, l’object UIHelper rappresenta un esempio di Singleton, poiché incapsula in un’unica istanza la logica di creazione e gestione di componenti UI comuni. In questo modo si ottiene una centralizzazione delle utility grafiche, rendendo il codice più pulito e riutilizzabile.
Il controller si occupa di gestire l’andamento del gioco facendo collaborare la logica e la grafica. La comunicazione con la logica viene fatta attraverso la collezione di logiche del tipo MiniGameLogic (implementato tramite il pattern Strategy visto prima). La comunicazione con la grafica, invece, viene fatta tramite il trait GameViewCallback. Questo contratto viene implementato dalle view in modo che, quando il controller produce un nuovo evento potrà richiamare direttamente i metodi del trait. I due eventi previsti sono:
Infine, il controller tiene traccia delle risposte dell’utente salvandole in una collezione di QuestionResult.
Il codice è stato diviso in package in base alle funzionalità. Nello specifico, il progetto presenta quattro moduli: