组合和聚合引用相同的 class (UML / TypeScript)

Composition and Aggregation referencing the same class (UML / TypeScript)

Hero有没有聚合和组合关系,有没有可能,有意义吗?

我的目标是为每个英雄保留一份权力列表,但是在创建一个权力时,应该只能添加一个权力而不是多个权力。这就是为什么我只为一个力量创造了一个私有属性力量的原因。

我的问题是关于 UML class 图的有效性。这是表达我的意图的正确方式吗?

power 是一个聚合的原因是它可能是另一个 class 使用相同的 power 实例(我已经实现了一些缓存,它总是 return 相同的 power 实例,因为简单我没有显示那部分)。

powers 是一个组合的原因是它强烈依赖于英雄实例。如果英雄被摧毁,权力也应该被清理。

UML 的代码看起来确实像那样 (TypeScript):

hero.ts

import { Power } from './power';

export class Hero {
  powers: Power[] = [];

  constructor(private power?: Power) {
    if (power) {
      this.addPower(power);
    }
  }

  addPower(power: Power) {
    this.powers.push(power);
  }

}

power.ts

export class Power {
  constructor(private title: string) { }
}

首先:两个类之间可以有一个Aggregation和Composition。你说的对,如果我们的part class要用whole class删掉,就用Composition,如果不行,就用Aggregation(或者Association)。有可能两者都在一个方向上(正如你所拥有的,只有递归关系是不可能的)

根据您的解释:

My aim is to keep a list of powers for each hero, however when creating one it should only be possible to add one Power instead of multiple Powers. That is the reason why i've created a private attribute power for only one power.

没有 HeroPower 之间的聚合。那只是 它们之间存在 Dependency 关系。根据您的代码和解释,您没有在代码中保存 ONE power,仅用于在 Hero 中将实例设置为 POWERS。这意味着您的 Hero 没有任何单个 Power 作为 part class.


但是,你的构图是完全正确的。因为你说:

it strongly depends on the hero instance. If hero is destroyed, powers should also be cleaned.

解决方案 基于 UML 中接受的答案:

在 TypeScript 中,最好不要实例化 Power 类型的属性,因为它没有其他用途。因此,构造函数只是获得一个 Power 并将其添加到 powers 数组中。

hero.ts

import { Power } from './power';

export class Hero {
  powers: Power[] = [];

  constructor(power?: Power) {
    if (power) {
      this.addPower(power);
    }
  }

  addPower(power: Power) {
    this.powers.push(power);
  }

}