Come giocatore, ho riscontrato i seguenti problemi relativi alla creazione e all'utilizzo di "estensioni" (alias mod) per i giochi:
1) Whenever the game is updated, all the mods break.
2) Most mods don't work with each other, so the player "has to choose"
3) If you ever de-install a mod, your "saved games" almost always become unusable.
Voglio progettare un gioco in Scala / Java che NON mostri questi problemi. Ho bisogno di aiuto con il punto 2. Voglio scriverlo in modo tale che sia massimamente estensibile. Il mio problema è che non riesco a inchiodare correttamente come dovrei fare questo, e dal momento che l'intero progetto risiede in cima all'architettura componente / servizio / plugin, che non posso andare avanti fino a quando non ho risolto questo problema.
Le qualità di design che voglio raggiungere sono:
1) For any "service", there should be a single object (at any given time) that implements it. Since it is a cycle-based simulation, I can safely "swap implementation" between the cycles.
2) It should be possible for a "third party" to create a "bundle" which either modifies or more likely extends the functionality of a "service", and "bind" it into the existing application at runtime, without recompilation.
3) It should be possible to load and unload those bundles at runtime, because they will be used in a long-running server.
4) Developing extensions should be easily possible, even for a "junior" programmer, without requiring extensive knowledge of some complex framework.
5) It should be possible for several bundles to extend/modify the same service at the same time, as long as they follow a certain set of rules preventing most conflicts.
Prima stavo progettando di usare OSGi, ma non riesco davvero a vedere come farlo funzionare. La soluzione OSGi consiste nel consentire a molti bundle di registrare lo stesso servizio e utilizzare un "filtro" per sceglierne uno nel codice client. Rendendo il codice consapevole che in un dato momento, ci possono essere diversi oggetti che implementano diverse varianti dello stesso servizio, e che tali istanze possono andare e venire, renderebbero tutto troppo complicato e fragile.
Il mio piano era di registrare ogni servizio come un "handle" generico, che l'utente del servizio può utilizzare per ottenere l'istanza e il cast reali su ciò che vogliono. Il contenuto dell'handle potrebbe cambiare nel tempo, ma l'oggetto handle stesso sarebbe valido per la durata del programma, ignorando quindi l'interrogazione costante del registro, con il filtro associato.
Penso che OSGi possa risolvere da 2 a 5, ma solo usando più istanze dello stesso servizio, che è in contraddizione con 1. Penso che 1 si possa ottenere usando la composizione, o fondendo tutte le diverse implementazioni di un servizio in un singolo oggetto tramite manipolazione del codice byte. Uno sguardo a Javaassist mi ha mostrato che "ridimensionare" una classe non sembra troppo difficile, se tutti estendono la stessa classe base e prendono gli stessi parametri del costruttore. La composizione, d'altra parte, sembra mettere molto più lavoro nelle mani degli sviluppatori di estensioni di terze parti, che è in contraddizione con 4, e generalmente è una soluzione goffa al meglio.
Se implemento la strategia di manipolazione del codice byte, allora sostanzialmente devo fare quasi tutto io stesso e perdere la maggior parte dei benefici di OSGi. Inoltre, non riesco a creare il servizio di fusione fintanto che non sono stati attivati tutti i pacchetti , quindi non possono registrare un'istanza di servizio "reale" al momento dell'attivazione, che è ciò che OSGi tratta (?). So già da OSGi quando è "finito"?
L'unico modo per raggiungere questi obiettivi è creare un mio framework di componenti, o posso ancora farlo usando OSGi o qualche altro sistema? Reinventare la ruota a quel livello sembra un'idea stupida (e che richiede tempo), ma non riesco a vedere come risolvere questi problemi con OSGi. Forse un altro framework di servizio / plugin può farlo? O utilizzando una strategia di progettazione ben definita specifica?
UPDATE: Sarà un modello Client-Server Internet (Cluster) in esecuzione su OpenGL. Io sono per lo più "quadro privo di ostacoli", cioè posso scegliere qualunque cosa si adatta alle mie esigenze, ma voglio attenermi alla JVM. OSGi è un tentativo di standardizzare "componenti" (chiamati bundle) per JVM.