У меня есть класс с большим количеством методов.Давайте не будем здесь останавливаться на том, что, вероятно, этот класс может быть реорганизован и переписан как несколько классов, потому что это будет в конечном итоге, но не знаю.Я хотел бы иметь декоратор, который украшает только один метод этого класса.Мы можем сделать это несколькими способами.
Интерфейс класса:
interface IFoo {
method1 (): number;
method2 (a: string): number;
method3 (b: IFoo): number;
method4 (c: string | (() => string)): number;
method5 (d: number, e: string): number;
}
Классическое решение ООП: определить декоратор, который переопределяет определенные методы,и просто вызов супер реализации для всех остальных.Примерно так.
class FooDecorator implements IFoo {
constructor (
private readonly provider: IFoo
) {}
public method1 (): number {
return this.provider.method1() + 1;
}
public method2 (a: string): number {
return this.provider.method2.apply(this.provider, arguments);
}
public method3 (b: IFoo): number {
return this.provider.method3.apply(this.provider, arguments);
}
public method4 (c: string | (() => string)): number {
return this.provider.method4.apply(this.provider, arguments);
}
public method5 (d: number, e: string): number {
return this.provider.method5.apply(this.provider, arguments);
}
}
Как видите, довольно долгое написание и дублирование кода.
Попробуйте использовать некоторые возможности JS.
interface IFooDecorator {
method1: IFoo["method1"];
}
class FooDecorator implements IFooDecorator {
constructor (
private readonly provider: IFoo
) {
Object.setPrototypeOf(this, provider);
}
public method1 (): number {
return this.provider.method1() + 1;
}
}
Очевидными недостатками являются неправильная типизация и использование setPrototypeOf
Я также пытался использовать Proxy, но также слабая поддержка типизаций с использованием прокси.Есть ли другие решения для этого?Первый подход хорош, если мы можем автоматизировать переопределение методов без декорации с помощью вызова .apply
.