javascript - 强制子类不可变

标签 javascript oop typescript design-patterns immutable.js

我有一个具有一些属性的基类:

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/

相关文章:

javascript - 为大型代码库编写适当的可维护可读 jQuery 的行业和社区最佳实践是什么?

javascript - jQuery 和面向对象的 JavaScript - 怎么样?

typescript - 如何限制 typescript 中的枚举字符串值

javascript - 在分配滚动监听器之前更新 scrollTop 会触发滚动事件

javascript - 如何使用setState()的回调?

javascript - js/jquery : issue with object key called "length"

c++ - 一个变量或对象的内存在程序结束时自动终止,而不是为什么我们使用析构函数?

javascript - TypeScript 定义外部类

angular - 如何修复错误 : ASSERTION ERROR: Should be run in update mode [Expected=> false == true <=Actual]

JavaScript 按钮停止页面上的所有音频