用装饰器设计模式覆盖内部方法

时间:2019-06-14 06:39:38

标签: oop design-patterns decorator

我正在编写一个面向对象的代码,其中我试图使用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设计模式来实现此功能吗?如果是,如何解决;如果不是,那么解决该问题的合适设计模式是什么。

谢谢。

2 个答案:

答案 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)