【问题标题】:Forcing Subclasses to Be Immutable强制子类是不可变的
【发布时间】:2017-05-29 14:24:50
【问题描述】:

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

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

所有的类都只是数据;没有行为(如果有任何行为,它将在静态方法中,而不是实例方法中)。现在我想尽可能地强制子类是不可变的(在允许修改的意义上,但是进行更改会导致一个新对象或抛出一个错误,如 Immutable.js),我无法找出最好的方法来做到这一点。

我想出的最好的办法是让每个子类都有一个只读的data 成员,它是一个带有适当字段的Immutable.Record,但即使这样也不太正确,因为更改它会返回一个新的data 对象,但我真的想要一个全新的Component 对象,这也并没有真正强制所有组件都遵循这个约定。

我考虑过的另一件事是让基类成为带有data: Immutable.Map 字段的Immutable.Record,然后子类为super 构造函数提供一个Immutable.Map 以及所有键,然后是人可以随意添加新键,这也不理想。

这里有什么神奇的设计模式可以帮助我吗?

【问题讨论】:

  • 这是一个相当难以理解的段落。通常最好将段落限制为 2-3 个句子,然后是一个新段落(在合理范围内)。

标签: javascript oop typescript design-patterns immutable.js


【解决方案1】:

使用Readonlymapped 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-04
    • 1970-01-01
    • 2010-11-20
    相关资源
    最近更新 更多