2

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 = []
1

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.

1

...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
    Thanks for this, there is a Python implementation called jsonref that supports serializing circular refs. – Lorenzo Mar 25 '15 at 20:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.