当前位置: 代码迷 >> JavaScript >> 类层次结构:是否有一种更简洁的模式?
  详细解决方案

类层次结构:是否有一种更简洁的模式?

热度:83   发布时间:2023-06-05 09:44:48.0

我在ES2015中写这个,但是这个问题也可以用其他语言解决。

在我的情况下,我有一个像这样的Chat类:

// 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);

现在,此类在createRoom()某个地方使用了User 问题在于User类需要利用我们导出的Chat实例:

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

但是现在我们在Chat.jsUser.js之间有了一个依赖循环。 该脚本将无法运行。 解决此问题的一种方法是永远Chat.js直接导入Chat.js ,而是执行以下操作:

// 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

但是现在,所有其他类都依赖于Chat并且一旦实例化它就必须给它提供对聊天实例的引用 这也不干净,不是吗? Chat现在是单点故障,以后很难交换。

有没有更清洁的方式来管理这个?

更新

显然, User不应该进行Chat 因此,聊天应如下所示

class Chat{
   //other declarations

  addUser(user,room) {}

  createSpecificRoom(user,name){}

  moveUserToRoom(user,newRoom) {}
}

如果要从用户对象执行操作,则可以使用双重调度。

class User{
  joinChat(chat,room){
      chat.addUser(this,room);
  }
}

var chat=new Chat();
var user= new User();
user.joinChat(chat,room);

但是,IMO最好的办法是仅使用Chat来添加/删除用户。 从语义上讲,它是跟踪房间和用户的工作。 关于单例,好吧,如果您使用的是支持DI的框架,那么几乎任何服务都是单例的,但您不必在意。 只要在您需要的任何地方插入Chat

  相关解决方案