gpt4 book ai didi

javascript - 使用 ES6 类继承进行参数化验证的值

转载 作者:行者123 更新时间:2023-11-29 19:12:29 30 4
gpt4 key购买 nike

我正在重写一些旧的 Chrome 扩展代码,同时尝试学习新的 ES6 技巧,我遇到了一些设计问题。

我的目标是提供一个值存储(由异步 chrome.storage 支持以实现持久性,但这超出了问题的范围)。我想要的是将一些验证与值相关联。因此,我的 StorageValues 的集合,每个值都与一个验证函数相关联。

在我的旧版本中,当我实例化一个值时,我只会传递一个验证函数,就像这样(简化):

Storage["key1"] = new Value({
validator: ValidatorIsInteger, defaultValue: 0, /* ... */
});
Storage["key2"] = new Value({
validator: ValidatorEnum(["a", "b", "c"]), defaultValue: "a", /* ... */
});

不过,我正在尝试用 Value 重写它,使其成为一个 class ,可以使用特定的验证器进行扩展,这在当时看来是个好主意。再次简化:

class Value {
constructor(key, defaultValue) {
this.key = key;
this.defaultValue = defaultValue;
this.set(defaultValue);
}

set(newValue) {
var validationResult = this.validate(newValue);
if (validationResult.pass) {
this.value = newValue;
return newValue;
} else {
throw new RangeError(
`Value ${newValue} for ${this.key} failed validation: ${validationResult.message}`
);
}
}

get() { return this.value; }

// Overload in children
validate(value) {
return {pass: true};
}
}

class IntegerValue extends Value {
validate(value) {
if (Number.isInteger(value)) {
return {pass: true};
} else {
return {pass: false, message: "Value must be an integer"};
}
}
}

到目前为止一切顺利。但是,我遇到了 problems尝试制作参数化子类时:

class EnumValue extends Value {
constructor(key, defaultValue, possibleValues) {
this.possibleValues = possibleValues; // NUH-UH, can't set that before super()
super(key, defaultValue);
}

// Will be called from parent constructor
validate(value) {
if (this.possibleValues.includes(value)) {
return {pass: true};
} else {
return {pass: false, message: `Value must be in [${this.possibleValues}]`};
}
}
}

问题在于在调用 .set(defaultValue) 之前“设置”参数化验证器。我看到了几种解决方法,但似乎都缺乏:

  • 辞职,不使用基于扩展的方法 - 我想先看看它是否可以修复
  • 始终相信默认值作为调用 .set(defaultValue) 的变通方法 - 不好,因为我不想意外地出现不一致的数据
  • 使 .set() 异步,使构造函数有机会在执行验证之前完成 - 虽然持久性后端是异步的,但 Storage 的目的除其他事项外,是提供同步“缓存”

我是否没有看到对这种方法的一些明显修复?如果不是,而且这只是工作的错误工具,我应该如何重新组织它?

最佳答案

这是从构造函数调用可覆盖方法(validate,通过set)的经典问题; discussed here (不同的语言,同样的问题)。

您的特定示例适用于一些解决方法,但一般问题仍然存在。

为了解决一般问题,我会直接设置 value,而不是通过 set,并使用单元测试来确保我没有创建具有无效的默认值。毕竟,这是编码错误,而不是运行时错误。

但是如果你想继续调用set,有几个选项:

  • 您可能有一个 Value 的概念,它没有 没有默认值,这在一般情况下可能很有用。这将通过让您拥有一个不期望接收默认值的 Value 构造函数来解决问题。您可以通过 setDefaultValue 或类似方法在构建后为 Value 提供默认值;该方法会验证,但这没关系,因为它会在子类中被称为构建后。

  • 你可以给 Value 一个“validating”和“non-validating”状态,并让构造函数接受一个标志,表示它应该从哪个状态开始。子类将使用 false 如果他们有特殊的验证行为,确保他们所有的鸭子都排成一行,然后设置验证状态(这将验证)。

关于javascript - 使用 ES6 类继承进行参数化验证的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37776479/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com