javascript - 类层次结构 : Is there a cleaner pattern for this?

标签 javascript oop design-patterns ecmascript-6

我是用 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
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,并且一旦我们实例化它,就必须为其提供对聊天实例的引用。这也不干净,是吗? 聊天现在是一个单点故障,以后很难进行交流。

是否有更简洁的方法来管理此问题?

最佳答案

已更新

显然,用户不应该有聊天。所以,聊天应该是这样的

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 的框架,几乎任何服务都是单例,但您不应该关心这一点。只需在需要的地方注入(inject) Chat 即可。

关于javascript - 类层次结构 : Is there a cleaner pattern for this?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31640323/

相关文章:

c++ - 在子类中初始化父类的 const 成员

java - Android 应用程序中的 MVP 与事件驱动

design-patterns - 服务层方法应该使用实例还是ID?

c++ - 发布者订阅者模式的现代替代方案

javascript - ASPX 页面中引用的文件不会导致调用 Application_BeginRequest

javascript - 正则表达式匹配 A、AB、ABC,但不匹配 AC。 ("starts with")

javascript - Angular 模块未正确加载

javascript - 多个数组到 JavaScript 对象

来自类的c++第二个函数无法访问第一个

java - Arrays.BinarySearch 是否要求数组按升序排序