我正在编写一个面向对象的代码,其中我试图使用Decorator模式来实现要在运行时应用于一系列核心类的各种优化。核心类的主要行为是在这些类中完全实现的复杂行为,它的确调用其他内部方法来完成任务。 装饰器将仅自定义内部方法,这些方法由核心类中的复杂行为调用。
这是我要达到的目标的伪代码:
interface I{
complex();
step1();
step2();
}
class C implements I{
complex(){
...
this.step1();
...
this.step2();
}
step1(){
...
}
step2(){
...
}
}
abstract class Decorator implements I{
I wrapped;
constructor(I obj){
this.wrapped = obj;
}
complex(){
this.wrapped.complex();
}
step1(){
this.wrapped.step1();
}
step2(){
this.wrapped.step2();
}
}
class ConcreteDecorator extends Decorator{
constructor(I obj){
super(obj);
}
step2(){
... // customizing step2()
}
}
有多种可以组合在一起的自定义项,这就是我使用装饰器模式的主要原因。否则,我将为每种可能的自定义组合创建数十到一百个子类型。
现在,如果我尝试创建装饰类的对象:
x = new C();
y = new ConcreteDecorator(x);
y.complex();
我希望complex()
方法从包装的核心对象中执行,同时使用装饰器中重写的step2()
方法。但是,由于抽象装饰器中的complex()方法直接在核心对象上调用该方法而确实跳过了装饰器中被覆盖的step2()
,因此这种方法无法正常工作。
我的总体目标是使装饰器仅覆盖stepx()
方法中的一个或几个,并将由已经在核心对象中实现的complex()
方法调用,并调用所有步骤。
可以完全使用Decorator设计模式来实现此功能吗?如果是,如何解决;如果不是,那么解决该问题的合适设计模式是什么。
谢谢。
答案 0 :(得分:1)
您面临的问题是,在应用Decorator设计模式时,由于您未装饰CASE VBRK-FKART.
WHEN 'RE' OR 'S1' OR 'SV'.
invoicedqnt = VBRP-FKIMG * -1.
WHEN 'G2' OR 'ZG2' OR 'IV'.
invoicedqnt = 0.
WHEN OTHERS.
invoicedqnt = VBRP-FKIMG.
ENDCASE.
,因此对装饰器对象上的complex()
的调用将委派给装饰的对象,具有complex()
的“普通”版本。
我认为解决问题的一种更合适的设计模式是Template Method设计模式。
在您的情况下,step2
将扮演 template方法的角色,该方法的步骤可以由子类自定义。不用继承,而是使用继承,其余部分或多或少保持不变。
以下是模板方法设计模式在您的上下文中的示例应用程序:
complex()
答案 1 :(得分:1)
我想您可以使用Strategy模式解决该问题,其中Strategy接口包括因类而异的方法。策略界面可能只包含一种方法,也可能包含多种方法,具体取决于它们的性质。
interface IStrategy {
step1(IData data);
step2(IData data);
}
interface I {
complex();
}
class C implements I {
IData data
constructor(IStrategy strategy) {}
complex() {
...
this.strategy.step1(this.data);
...
this.strategy.step2(this.data);
}
}
class S1 implements IStrategy {
constructor(IStrategy strategy)
step1(IData data) {
}
step2(IData data) {
}
}
strategy1 = new S1();
c = new C(strategy1)