我有一个具有一些属性的基类:
class Component {
readonly id: number
readonly type: number
}
我想要一些子类:
class HealthComponent extends Component {
max_health: number,
current_health: number
}
etc.
我想要的基本上是让 HealthComponent
具有与 Immutable.Record
相同的行为:
const health = HealthComponent(100, 100);
health.max_health = 40; // Shouldn't work
const new_health = new HealthComponent(40, health.current_health); // Works
所有的类都只是数据;没有行为(如果有任何行为,它将在静态方法中,而不是实例方法中)。现在我想尽可能地强制子类是不可变的(在允许修改的意义上,但进行更改会导致新对象或抛出错误 la Immutable.js)而且我无法找出最好的方法来做到这一点。
我想出的最好的办法是让每个子类都有一个只读的data
成员,它是一个具有适当字段的Immutable.Record
,但即使这不太正确,因为更改它会返回一个新的 data
对象,但我真的想要一个全新的 Component
对象,而且这也并没有真正强制执行所有组件遵循此约定。
我考虑过的另一件事是让基类成为一个 Immutable.Record
和一个 data: Immutable.Map
字段,然后子类提供一个 Immutable.Map
到带有所有键的 super
构造函数,但随后人们可以随意添加新键,这也不理想。
有没有神奇的设计模式可以帮到我?
最佳答案
使用Readonly
mapped type .
class Component {
constructor(public id: number, public type: number) {
}
}
class HealthComponent extends Component {
constructor(public id: number, public type: number, public max_health: number, public current_health: number) {
super(id, type);
}
}
let hc: Readonly<HealthComponent> = new HealthComponent(1, 2, 3, 4);
hc.max_health = 40; // Error
如果您没有行为,请考虑使用接口(interface)
。
interface Component {
id: number
type: number
}
interface HealthComponent extends Component {
max_health: number;
current_health: number;
}
let hc: Readonly<HealthComponent> = {
id: 1,
type: 2,
max_health: 3,
current_health: 4
};
hc.max_health = 40; // Error
关于javascript - 强制子类不可变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44244849/