我有一个接口MyInterface
和一个实现接口的具体实现MyImplementation
。现在我需要创建多个" Wrappers"这也应该实现MyInterface
并将包装原始的MyImplementation
对象。从某种意义上说,包装器上的属性和函数方法将作为一种Proxy
进行包装 - 即对输入数据执行一些检查并将其传递给MyImplementation
的原始实现。我需要将多个包装器堆叠到彼此中,即具有MyValidator1
,MyValidator2
等等,根据用例,可以添加到单个对象中。
一些使事情更清晰的代码:
interface MyInterface {
method1(arg1, arg2): any;
}
class MyImplementation implements MyInterface {
method1(arg1, arg2) {
/* perform checks and or throw */
}
}
class MyValidator1 implements MyInterface {
method1(arg1, arg2) {
/* ... */
}
}
class MyValidator2 implements MyInterface {
method1(arg1, arg2) {
/* ... */
}
}
let o1 = new MyImplementation();
// only apply validator1
AddValidator1(o1);
let o2 = new MyImplementation();
// only apply validator2
AddValidator2(o2);
let o3 = new MyImplementation();
// apply both validators
AddValidator1(o3);
AddValidator2(o3);
// intended call hierarchicy when calling o3.method1(arg1, arg2)
// MyValidator1.method1(arg1, arg2)
// MyValidator2.method1(arg1, arg2)
// MyImplemenation.method1(arg1, arg2)
// but the order of the validators is not important!
这只是一些代码建议,我正在寻找可能与上述代码不同的各种模式来实现这一目标。
将MyInterface
实现的所有实例封装起来非常重要 - 它们应该像消费者MyImplemenation
一样行事。验证器应该可以添加私有函数或属性。
这是最好的方法吗?也许在运行时改变原型?
答案 0 :(得分:0)
我不知道TypeScript,但是这里将如何在常规Javascript(ES6语法)中完成:
class MyInterface {
foo() {
throw new Error('To be implemented');
}
}
class MyImplementation extends MyInterface {
foo() {
return 42;
}
}
function wrapWithValidator1(impl) {
class MyValidator1 extends MyInterface {
constructor() {
for (const key of Object.keys(impl)) {
this[key] = impl[key];
}
}
foo() {
validateStuff();
return impl.foo();
}
}
return new MyValidator1();
}
function wrapWithValidator2(impl) {
class MyValidator2 extends MyInterface {
constructor() {
for (const key of Object.keys(impl)) {
this[key] = impl[key];
}
}
foo() {
validateOtherStuff();
return impl.foo();
}
}
return new MyValidator2();
}
您的验证器是实现的包装器,因为它们“扩展”它。它们继承自实现原型(及其所有属性/方法),但它们可以覆盖现有方法以提供其他行为。
覆盖调用父方法的方法时使用super.myMethod()
。
答案 1 :(得分:0)
如何在MyImplementation
班级中列出验证人员?
类似的东西:
abstract class Validator implements MyInterface {
abstract method1(arg1, arg2): any;
}
class MyValidator1 extends Validator {
method1(arg1, arg2) {
/* ... */
}
}
class MyValidator2 extends Validator {
method1(arg1, arg2) {
/* ... */
}
}
class MyImplementation implements MyInterface {
private validators: Validator[];
constructor() {
this.validators = [];
}
addValidator(validator: Validator) {
this.validators.push(validator);
}
method1(arg1, arg2) {
this.validators.every(validator => { /* do something here */ return false; });
/* perform checks and or throw */
}
}