Menu
Coddy logo textTech

Tabella singleton

Fa parte della sezione Programmazione orientata agli oggetti del percorso Lua di Coddy. Lezione 63 di 70.

A volte hai bisogno di una sola istanza di qualcosa in tutto il programma: un gestore della configurazione, un sistema di registrazione o le impostazioni del gioco. Creare più copie causerebbe problemi: quale contiene i dati corretti? Il pattern Singleton garantisce che esista una sola istanza.

In Lua, implementare un Singleton è sorprendentemente semplice grazie al funzionamento dei moduli. Quando usi require per caricare un modulo, Lua memorizza nella cache il risultato. Le chiamate successive a require restituiscono la tabella memorizzata nella cache, non una nuova tabella.

-- GameConfig.lua
local GameConfig = {
    volume = 80,
    difficulty = "normal"
}

function GameConfig:setVolume(v)
    self.volume = v
end

return GameConfig

Ora, in qualsiasi punto del tuo programma:

local config1 = require("GameConfig")
local config2 = require("GameConfig")

config1:setVolume(50)
print(config2.volume)  -- 50 (stessa tabella!)

Sia config1 che config2 fanno riferimento alla stessa identica tabella. Le modifiche apportate tramite una variabile sono visibili anche tramite l’altra. Questo avviene automaticamente perché Lua memorizza il valore restituito da require in package.loaded e lo riutilizza.

A differenza del pattern Factory, che crea nuovi oggetti, un Singleton garantisce uno stato condiviso in tutta l'applicazione. È ideale per le impostazioni globali a cui più parti del codice devono poter accedere e apportare modifiche in modo coerente.

challenge icon

Sfida

Facile

Creiamo un gestore delle impostazioni di gioco usando il pattern Singleton! Creerai un modulo di configurazione che garantisce che ogni parte del tuo programma acceda esattamente alle stesse impostazioni, indipendentemente da quante volte venga richiesto.

Organizzerai il codice in due file:

  • GameSettings.lua: crea un modulo Singleton che memorizza la configurazione del gioco. La tabella delle impostazioni deve includere musicVolume (inizializzato a 70), sfxVolume (inizializzato a 100) e difficulty (inizializzato a "normal"). Aggiungi tre metodi: :setMusicVolume(value), :setSfxVolume(value) e :setDifficulty(level) per modificare queste impostazioni. Ricorda di restituire la tabella alla fine del modulo!
  • main.lua: dimostra che il Singleton funziona richiedendo il modulo GameSettings due volte e assegnandolo a variabili diverse. Usa la prima variabile per modificare il volume della musica e la difficoltà. Poi usa la seconda variabile per stampare tutte e tre le impostazioni. Se il Singleton funziona correttamente, entrambe le variabili fanno riferimento alla stessa tabella, quindi le modifiche apportate tramite una sono visibili anche tramite l’altra.

Riceverai due input:

  1. Nuovo volume della musica (un numero)
  2. Nuovo livello di difficoltà (una stringa come "easy" o "hard")

Dopo aver modificato le impostazioni tramite la prima variabile, stampa le tre impostazioni usando la seconda variabile, ciascuna su una riga, in questo ordine: volume della musica, volume degli effetti sonori, poi difficoltà.

Ad esempio, se gli input sono 50 e hard, l’output dovrebbe essere:

50
100
hard

Se gli input sono 25 e easy, l’output dovrebbe essere:

25
100
easy

Nota che il volume degli effetti sonori rimane al valore predefinito di 100, poiché non lo abbiamo mai modificato, mentre il volume della musica e la difficoltà riflettono le modifiche apportate tramite la prima variabile, dimostrando che entrambe le variabili puntano alla stessa istanza Singleton!

Provalo tu

-- main.lua - Illustra il pattern Singleton

-- Leggi gli input
local newMusicVolume = tonumber(io.read())
local newDifficulty = io.read()

-- TODO: importa il modulo GameSettings in una variabile (ad es., settings1)

-- TODO: importa NUOVAMENTE il modulo GameSettings in una variabile DIVERSA (ad es., settings2)
-- (Se Singleton funziona correttamente, entrambe le variabili fanno riferimento alla stessa tabella!)

-- TODO: usa la PRIMA variabile per:
--   - Impostare il volume della musica su newMusicVolume
--   - Impostare la difficoltà su newDifficulty

-- TODO: usa la SECONDA variabile per stampare le impostazioni
-- Stampa ciascun valore su una riga separata: musicVolume, sfxVolume, difficulty
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Lua online