【问题标题】:How do I avoid a circular dependancy when the base class adds an extended class?基类添加扩展类时如何避免循环依赖?
【发布时间】:2020-08-12 05:56:05
【问题描述】:

我正在使用从容器类扩展而来的类。类的每个实例本身就是一个容器,但顶级容器不是该类的实例。

文件 1

const Command = require('Command');
class CommandManager {
    constuctor () {
        this.commands = {};
    }
    add (object) {
        const command = new Command(object);
        this.commands[command.name] = command;
    }
    get (string) {
        return this.commands[string];
    }
}

文件 2

const CommandManager = require("CommandManager");
class Command extends CommandManager {
    constructor (object) {
        super();
        //Other-code
    }
    // Class Methods
}

在运行时它应该看起来像这样:

client.commands = new CommandManager();
client.commands.add(object); // Add function also filters down adding to sub elements

或者:

const command = client.commands.get(string);
command.add(object);

问题是这些文件中至少有一个以空对象或所需类未定义而告终。我尝试遵循其他节点循环依赖解决方案的尝试没有奏效(或者我没有正确理解它们)。

目的是将 2 个类保存在它们自己的文件中,我知道我可以通过使用同一个文件来解决问题(但这将是项目中的一个例外?),我不确定我如何(或消费者)会在逻辑上要求它,因为他们在不同的领域。

那么我可以通过哪些方式来解决这个问题?

【问题讨论】:

  • a) 使用依赖注入(将Command 类传递给CommandManager 构造函数-“这是创建您将管理的命令的方法”)b)使require('Command') 变得懒惰在add 方法中移动它。 Command.js 模块可以在调用add 之前解析其非循环依赖。
  • 也就是说,我本来希望继承层次结构反过来 - 每个命令都是一个 Command 实例,但其中只有一些是命令容器。
  • @Bergi 在这种情况下,每个命令都是一个容器,虽然其中一些可能不会使用它,但我无法区分它们是否会。其他人会发出命令,而 Command 实例不能有“可能的属性”。如果特定命令需要容器,您可以检查一系列标志并检查“解决方案”,但这会在内部添加处理并强制消费者使用这些标志。
  • 如果每个命令都是(或:可以充当)容器,我不明白为什么首先会有两个单独的类。此外,那个“顶级容器”:为什么不也是一个命令?
  • @Bergi 懒惰的吸气剂似乎正是我所需要的。您能再写一次作为答案,以便我将其标记为一个吗?我也不太确定,但是做一个“让命令”更好吗? “如果(!Command)Command = require”还是每次都需要命令(因为模块被缓存)?

标签: javascript node.js class require circular-dependency


【解决方案1】:

根据 Bergi 发表的评论:

在 CommandManager 文件中将 require 设为惰性会延迟模块的加载,并允许在调用之前解决依赖关系。

class CommandManager {
    constuctor () {
        this.commands = {};
    }
    add (object) {
        const Command = require('Command');
        const command = new Command(object);
        this.commands[command.name] = command;
    }
    get (string) {
        return this.commands[string];
    }
}

【讨论】:

  • 这是一个很棒的解决方案!感谢 Aquellia 的精彩提示。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-02-06
  • 1970-01-01
  • 2018-09-03
  • 2012-02-15
  • 2013-04-02
  • 2020-10-16
  • 2012-04-14
相关资源
最近更新 更多