Ho letto le risposte a Perché lo stato globale è così malvagio? , e penso che le conseguenze negative non si applichino in questa situazione. Tuttavia, questo è quello che tutti dicono poco prima di essere colpiti da un pianostrong in caduta e le mie lezioni di architettura del software sono state qualche anno fa, quindi ...
Stiamo sviluppando un'applicazione di chat desktop in Python. In quella applicazione, c'è uno stato intrinsecamente globale: configurazione account, classi client (dalla libreria del protocollo chat) per quegli account, conversazioni aperte, ecc.
Nel progetto attuale, utilizziamo singole istanze globali per il controller account e il controller client (gestendo gli oggetti client dalla libreria chat che stiamo utilizzando) e il controller di conversazione (gestendo le astrazioni di conversazione per le sessioni di chat comprese le chat di gruppo ). Queste istanze globali sono disponibili ovunque tramite un semplice import foo.app as app
. I controller hanno modelli associati e le visualizzazioni di sola lettura su questi modelli possono essere istanziate in modo indipendente in vari punti dell'applicazione.
Si applicano le seguenti osservazioni:
- Il test delle unità funziona bene finora: possiamo tranquillamente deridere quelle istanze globali con Pythons
unittest.mock
(infatti, le istanze sono solo inizializzate durante l'effettivo avvio dell'applicazione, quindi sonoNone
altrimenti - > instant e errore evidente se non viene deriso ma utilizzato nei test). - La modifica dello stato dei dati globali associati ai controller passa solo attraverso i controller; e la modifica dello stato emette segnali di callback ben definiti in modo che i consumatori dello stato possano ottenere aggiornamenti.
- Il codice ha concurrency, ma sta usando l'asyncio di Python: questo implica multitasking cooperativo, quindi i punti in cui altri task possono interferire sono ben definiti e ovvi nel codice (quando usiamo thread reali, stato globale non sarà possibile accedere direttamente). Quindi è sicuro assumere che lo stato globale non cambi all'interno di un metodo (non di coroutine).
- La maggior parte degli usi dello stato globale sono semplici ricerche del tipo "Quale oggetto client è associato all'account X?", "Ottieni l'oggetto conversazione sull'account X con peer Y", "Quali account e identità esistono?" e iscrivendosi agli aggiornamenti.
Ora mi chiedo: abbiamo trascurato qualcosa? E se sì, quale sarebbe la correzione appropriata? Sento che questo progetto potrebbe funzionare abbastanza bene, ma temo che potremmo aver trascurato qualcosa di rilevante che cadrà in piedi in un secondo momento.