在 Typescript 中重构循环依赖

JME*_*JME 5 typescript angular

我有一个 API,它对导致循环依赖的数据进行非规范化。有没有办法使用抽象类、接口、组合或其他技术来重构以下内容,我不需要为每个实体创建 N 个部分类以避免我的 Angular 应用程序的类型定义中的循环依赖?

模型.ts

export abstract class Model {
  // ... Model related data members and functions
}
Run Code Online (Sandbox Code Playgroud)

人.ts

import { Model } from './model';
import { Site } from './site';

export class Person extends Model {

  // ... Data

  site: Site; // Partially or Fully saturated site entity
}
Run Code Online (Sandbox Code Playgroud)

网站.ts

import { Model } from './model';
import { Person } from './person';

export class Site extends Model {

  // ... Data

  people: Person[]; // array of partially saturated people entities, site is left undefined
}
Run Code Online (Sandbox Code Playgroud)

我想保持一个定义每个模型,而不是重新定义SitePerson每个时间等有这样的依赖。

adr*_*ons 5

这个问题是由糟糕的类模型设计引起的,并且与语言无关。我希望这有帮助 :)

\n

循环依赖问题一般包括先有鸡还是先有蛋的问题,因为当你要实例化一个对象时,你不知道应该先实例化哪个对象。

\n

\xc2\xa0解决方案 1

\n

这个问题可以通过仅通过对象的身份引用对象来轻松解决,而不是直接依赖于大对象作为构造函数的一部分。例如修改Person类:

\n
import { Model } from \'./model\';\n\nexport class Person extends Model {\n\n  // ... Data\n\n  siteId: number;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

\xc2\xa0解决方案 2

\n

如果您需要 Person 内的完整对象,我认为一个好的方法是更改​​继承树。\n我了解您的数据模型是关于网站、其用户和所有者的。好吧,让我们分解一下:创建一个抽象类并用和类Person扩展它。UserOwner

\n

人.ts

\n
import { Model } from \'./model\';\n\nexport abstract class Person extends Model {\n\n  // ... Data\n  \n  // Does not include the Site attribute!\n}\n
Run Code Online (Sandbox Code Playgroud)\n

用户.ts

\n

Users将是 的“读者” Site,但不需要对其的引用。

\n
import { Person } from \'./person\';\n\nexport class User extends Person {\n\n  // ... Data\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n

所有者.ts

\n

Owner将成为 的创造者Site。这是引用Site.

\n
import { Person } from \'./person\';\n\nexport class Owner extends Person {\n\n  // ... Data\n\n  site: Site;\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n

站点.ts

\n

最后,它Site会跟踪其用户。

\n
import { Model } from \'./model\';\nimport { User } from \'./user\';\n\nexport class Site extends Model {\n\n  // ... Data\n\n  users: User[];\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我认为这篇相关文章可能有助于理解循环依赖:如何在 JavaScript & TypeScript 中一劳永逸地解决令人讨厌的循环依赖问题

\n


Kat*_*bhi 2

为什么不使用内部模块模式来导出所有类并由模型在内部使用来加载依赖项。

示例应用程序:https://codesandbox.io/s/circular-deps-fix-using-internal-module-pattern-mtfro

内部.ts

export * from './model'
export * from './person'
export * from './site'
Run Code Online (Sandbox Code Playgroud)

模型.ts

export abstract class Model {
  // ... Model related data members and functions
}
Run Code Online (Sandbox Code Playgroud)

人.ts

import { Model, Site  } from './internal';

export class Person extends Model {

  // ... Data

  site: Site; // Partially or Fully saturated site entity
}
Run Code Online (Sandbox Code Playgroud)

站点.ts

import { Model, Person } from './internal';

export class Site extends Model {

  // ... Data

  people: Person[]; // array of partially saturated people entities, site is left undefined
}
Run Code Online (Sandbox Code Playgroud)

上述规则仅适用于我们本地的依赖项。外部模块导入保持原样。他们毕竟不涉及我们的循环依赖问题。