dimanche 26 juillet 2015

Class hierarchy: Is there a cleaner pattern for this?

I'm writing this in EcmaScript 6, but this problem can also be taken to other languages.

In my situation, I have a Chat class like this:

// Chat.js
import { socket, config } from "./Util.js";
import User from "./User.js";
class Chat {
    constructor(socket, config) {
        // …
    }
    roomExists(room) {
        // …
    }
    createRoom(room) {
        // …
    }
}
// Make sure to export the same instance to every other module,
// as we only need one chat (resembling a singleton pattern)
export default new Chat(socket, config);

Now, this class makes use of User somewhere in createRoom(). The problem is that the User class needs to make use of the Chat instance that we export:

// User.js
import chat from "./Chat.js";
export default class User {
     join(room) {
         if (chat.roomExists(room)) {
             // …
         }
     }
}

But now we have a dependency loop between Chat.js and User.js. This script won't run. One way to solve this would be to never import Chat.js directly, but do something like this:

// Chat.js
import { socket, config } from "./Util.js";
import User from "./User.js";
class Chat {
    constructor(socket, config) {
        // Pass `this` as a reference so that we can use
        // this chat instance from within each user
        this.userReference = new User(this);
    }
    roomExists(room) {
    }
    createRoom(room) {
    }
}
// No need to export a singleton anymore, as we pass the
// reference to the chat in the User constructor

But now, every other class depends on Chat and must be given a reference to a chat instance once we instantiate it. This isn't clean, either, is it? Chat is now a single point of failure and very hard to exchange later on.

Is there a cleaner way of managing this?

Aucun commentaire:

Enregistrer un commentaire