I’ve been stuck for some time on a circular reference issue with JSON serialization. I have a card game that I’m pickling to a redis store. As I retrieve the Game state from redis I’m trying to serialize it in JSON so that I can pass it to React.js and render it on screen. I mentioned React.js as my goal is to pass back and forth the entire game state at every change of state.
Below is the simplified code of my class structure. The Game class holds reference to everything. Player holds references to Game and Cards, Cards hold references to Player.
Is this design desperately wrong? Instead of referencing objects should I just be referencing their an ID of the object and then retrieve them separately when I have to render the new state? Any design pattern that could come useful?
If it could be useful to answer the question the stack I’m using is Python, Django, Redis, React
class Card(object):
def __init__(self, suit, face):
self.face = face
self.suit = suit
self.is_trump = False
self.owner = None
class Deck(object):
def __init__(self):
self.deck = []
class Player(object):
def __init__(self, name, autopilot=False):
self.score = 0
self.uid = self._new_uid()
self.name = name
self.cards = []
self.is_first = False # used to determine the winner in case of draw
self.autopilot = autopilot
# updated when the game is joined by the Game instance
self.game = None
class Game(object):
def __init__(self, players, deck, table):
self.hands = []
self.winner = None
self.players = players
self.uid = self._new_uid()
self.deck = deck
self.table = table
self.over = False
class Hand(object):
def __init__(self, carda, cardb, game, simulate=False):
self._carda = carda
self._cardb = cardb
self._first = self._get_first()
self._winner = self._play()
# is it a regular hand or a simulation?
if not simulate:
self._update_score()
game.table.clean()
game.hands.append(self)
class Table(object):
def __init__(self):
self.cards = []
self.played = []
To avoid circular references, only a parent node/class should know about it’s children.
Accessing Game as the root node should allow you to gather information anywhere you need.
…Is this design desperately wrong?
No. You can serialize circular references using JSON
I don’t know what’s the Python
-approach. But from the specification point of view I’ve heard that json pointer fragment
might be the internet search query
Wikipedia → JSON → Object references is not very clear on this subject and emphasizes the implementation used by dojox.json.ref JavaScript
toolkit
Newtonsoft’s Json.NET library (“standard” in the C#
world) supports object references fully using slightly different convention with "$id"
and "$ref"
special properties.
So in the C#
, JavaScript
worlds you would not have to flatten or restructure your graph-like data structures at all
…Any design pattern that could come useful?
Use the right tools for the job (stronger programming language or library)
1