ES6 循环依赖。实施依赖中心

ES6 circular dependency. Implementing dependency hub

我发现了很多关于循环依赖的文章,它表明了项目中的 design/architecture 缺陷。在大多数情况下,可以通过稍微重构您的 classes.

轻松修复它

在这个例子中,我试图为依赖项创建一个中心。这是一个 classes 的库,可以被不同的项目导入。目标是在主要 class 中有 getters,这将 return 一个依赖实例。这个实例必须是一个单例,并且它存储在主 class' 依赖项中,下次如果有人调用 getter - 它会 return 那个 class 的相同实例.

代码如下所示:

// deps

import { DepA } from './dep-a';
import { DepB } from './dep-b';

const depsKey = '__MY_DEPS__';

class Deps {
  dependencies = {};

  get depA() {
    return this.getDependency('depA', DepA);
  }  
  
  get depB() {
    return this.getDependency('depB', DepB);
  }  

  bind(key, value) {
    this.dependencies[key] = value;
  }

  getDependency(key, serviceClass) {
    let service = this.dependencies[key];

    if (!service && !!serviceClass) {
      // if instance is not created yet, we instantiate the class and put instance in the dependencies
      service = new serviceClass();
      this.bind(key, service);
    }

    return service;
  }
}

export const deps = (() => {
  window[depsKey] = window[depsKey] || new Deps();

  return window[depsKey];
})();

// dep-a

import { deps } from './deps';

export class DepA {
  methodA() {
    console.log(deps.depB);
  }
}

// dep-b

import { deps } from './deps';

export class DepB {
  methodB() {
    console.log(deps.depA);
  }
}

如您所见 - 这会产生循环依赖问题,因为 class Deps 在其 getter 中使用 classes DepA 和 DepB 来创建这些 classes 如果它不存在。 classes DepA 和 DepB 使用 Deps 的实例通过其 getters 相互检索。

希望这个解释不会很繁琐

任何人都可以建议我需要进行哪些更改以摆脱此处的循环依赖,但要保持通过 Deps class(deps 实例)访问单例的想法?

我的建议是:

a-singleton.js

import { DepA } from './dep-a'; 

let singleton;
export function getA() {
  if (!singleton) {
    singleton = new DepA();
  }
  return singleton;
}

b-singleton.js

import { DepB } from './dep-b'; 

let singleton;
export function getB() {
  if (!singleton) {
    singleton = new DepB();
  }
  return singleton;
}

然后在任何需要这些单例的地方,您可以导入文件并调用函数来获取单例。

根据这些 类 的作用以及它们 how/when 相互引用,您也可以直接执行 export default new DepA(),但取决于它们如何相互引用,以及引用的程度他们需要在实例化时执行,我在这里展示的惰性方法可能更好或必要。