如何处理接口构造函数,确保不同ErrorNotifier实现的数据访问一致性?
解决方案:用抽象类统一约束构造函数与属性
要解决这个问题,用抽象类是非常合适的选择——因为普通接口(比如你定义的ErrorNotifier)只能约束实例的方法签名,管不到构造函数的参数和公共属性,而抽象类可以同时定义公共属性、构造逻辑和必须实现的方法,强制所有子类遵守统一规则。
1. 定义抽象基类
先把所有错误通知类的公共部分抽离成抽象类:包含type、errors属性,以及接收这两个参数的构造函数,同时声明一个抽象的notifyInternally方法(只规定方法签名,不写具体实现):
abstract class BaseErrorNotifier { protected type: string; // 用protected让子类可访问,也可以用public protected errors: string[] | Error[]; constructor(type: string, errors: string[] | Error[]) { this.type = type; this.errors = errors; } // 抽象方法,子类必须实现自己的逻辑 abstract notifyInternally(): void; }
2. 改造现有Email通知类
让EmailErrorNotifier继承抽象类,调用父类构造函数后,实现自己的邮件发送逻辑:
class EmailErrorNotifier extends BaseErrorNotifier { constructor(type: string, errors: string[] | Error[]) { // 必须调用super传入父类要求的参数,否则编译/运行时会报错 super(type, errors); } notifyInternally(): void { // 直接使用父类传递的this.type和this.errors console.log(`发送邮件:错误类型【${this.type}】,详情:${JSON.stringify(this.errors)}`); // 这里写实际发邮件的逻辑 } }
3. 实现短信通知类
新的PhoneErrorNotifier必须遵循同样的规则:继承抽象类,调用super传入type和errors,再实现短信发送逻辑:
class PhoneErrorNotifier extends BaseErrorNotifier { constructor(type: string, errors: string[] | Error[]) { super(type, errors); } notifyInternally(): void { // 同样可以直接访问this.type和this.errors console.log(`发送短信:错误类型【${this.type}】,共${this.errors.length}个错误`); // 这里写实际发短信的逻辑 } }
为什么这能解决你的问题?
- 强制构造参数:抽象类的构造函数要求子类必须传入
type和errors——如果子类不调用super(type, errors)或者参数缺失,TypeScript会在编译时报错,纯JS环境也会在运行时抛出错误。 - 避免重复代码:公共属性
type和errors在父类定义,子类不需要重复声明,直接就能在notifyInternally里使用。 - 保证行为一致:抽象方法
notifyInternally强制所有子类实现自己的通知逻辑,确保所有错误通知类都符合ErrorNotifier的行为规范。
补充:纯JavaScript环境的实现(无TypeScript)
如果是在纯JS里开发,没有TypeScript的抽象类语法,可以用普通父类+运行时检查模拟约束:
class BaseErrorNotifier { constructor(type, errors) { // 禁止直接实例化父类 if (new.target === BaseErrorNotifier) { throw new Error("请继承BaseErrorNotifier,不要直接实例化"); } // 强制传入参数 if (!type || !errors) { throw new Error("必须传入type和errors参数"); } this.type = type; this.errors = errors; } // 强制子类重写方法 notifyInternally() { throw new Error("子类必须实现notifyInternally方法"); } } // 短信通知类实现 class PhoneErrorNotifier extends BaseErrorNotifier { constructor(type, errors) { super(type, errors); } notifyInternally() { console.log(`短信通知:${this.type} - ${this.errors.length}个错误`); } }
这种方式能在运行时强制约束子类行为,达到和抽象类类似的效果。
内容的提问来源于stack exchange,提问作者CaitlynCodr
相关产品推荐
相关产品推荐

