Initialization of components with interdependencies - possible antipattern?

Posted by Rosarch on Stack Overflow See other posts from Stack Overflow or by Rosarch
Published on 2010-04-02T03:39:27Z Indexed on 2010/04/02 3:43 UTC
Read the original article Hit count: 289

I'm writing a game that has many components. Many of these are dependent upon one another. When creating them, I often get into catch-22 situations like "WorldState's constructor requires a PathPlanner, but PathPlanner's constructor requires WorldState."

Originally, this was less of a problem, because references to everything needed were kept around in GameEngine, and GameEngine was passed around to everything. But I didn't like the feel of that, because it felt like we were giving too much access to different components, making it harder to enforce boundaries.

Here is the problematic code:

    /// <summary>
    /// Constructor to create a new instance of our game.
    /// </summary>
    public GameEngine()
    {
        graphics = new GraphicsDeviceManager(this);
        Components.Add(new GamerServicesComponent(this));

        //Sets dimensions of the game window
        graphics.PreferredBackBufferWidth = 800;
        graphics.PreferredBackBufferHeight = 600;
        graphics.ApplyChanges();

        IsMouseVisible = true;
        screenManager = new ScreenManager(this);

        //Adds ScreenManager as a component, making all of its calls done automatically
        Components.Add(screenManager);

        // Tell the program to load all files relative to the "Content" directory.
        Assets = new CachedContentLoader(this, "Content");

        inputReader = new UserInputReader(Constants.DEFAULT_KEY_MAPPING);

        collisionRecorder = new CollisionRecorder();

        WorldState = new WorldState(new ReadWriteXML(), Constants.CONFIG_URI, this, contactReporter);

        worldQueryUtils = new WorldQueryUtils(worldQuery, WorldState.PhysicsWorld);

        ContactReporter contactReporter = new ContactReporter(collisionRecorder, worldQuery, worldQueryUtils);

        gameObjectManager = new GameObjectManager(WorldState, assets, inputReader, pathPlanner);
        worldQuery = new DefaultWorldQueryEngine(collisionRecorder, gameObjectManager.Controllers);
        gameObjectManager.WorldQueryEngine = worldQuery;

        pathPlanner = new PathPlanner(this, worldQueryUtils, WorldQuery);

        gameObjectManager.PathPlanner = pathPlanner;

        combatEngine = new CombatEngine(worldQuery, new Random());
    }

Here is an excerpt of the above that's problematic:

        gameObjectManager = new GameObjectManager(WorldState, assets, inputReader, pathPlanner);
        worldQuery = new DefaultWorldQueryEngine(collisionRecorder, gameObjectManager.Controllers);
        gameObjectManager.WorldQueryEngine = worldQuery;

I hope that no one ever forgets that setting of gameObjectManager.WorldQueryEngine, or else it will fail. Here is the problem: gameObjectManager needs a WorldQuery, and WorldQuery needs a property of gameObjectManager.

What can I do about this? Have I found an anti-pattern?

© Stack Overflow or respective owner

Related posts about code-review

Related posts about design-patterns