【发布时间】:2015-07-26 18:12:18
【问题描述】:
我在 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.js 和User.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 现在是单点故障,以后很难交换。
有没有更简洁的管理方式?
【问题讨论】:
-
为什么
join(可能应该是joinRoom以避免与数组方法join混淆)是User而不是Chat的方法?Chat似乎可以管理房间的方方面面。 -
@JasonCust 因为语义上,
Users 应该join一个房间,但Chats 不应该加入任何东西。Chat管理createRoom,因为一些房间是由Chat(默认房间)创建的。稍后在User中还将有一个createRoom方法来启用用户制作的房间。 -
这个“
classsingleton”是definitively an antipattern。不要这样做。创建一个对象字面量。 -
@Chiru:您确实应该将用户加入的房间或聊天(房间)或用户在其中创建新房间的聊天作为参数传递给这些方法。不要将 Chats 设为单例。如果您的应用程序只需要一个 Chat,请在您的 App main 中创建一个实例。这正是单例反模式。
-
我同意,@Bergi,谢谢。我现在使用了对象字面量。
标签: javascript oop design-patterns ecmascript-6