装饰器模式失去虚拟方法查找.有什么好的替代方案或解决方法吗?

aio*_*obe 4 java oop virtual-functions decorator

背景

我遇到以下情况:

我的Analyzer类型大致如下

interface Analyzer {
    int computeValue();
    String performAnalysis();
}
Run Code Online (Sandbox Code Playgroud)

通过类似的东西实现

class AnalyzerImpl implements Analyzer {

    @Override
    public int computeValue() {
        return 5;
    }

    @Override
    public String performAnalysis() {
        return "Result: " + computeValue();
    }
}
Run Code Online (Sandbox Code Playgroud)

(在我的实际代码中,performAnalysis使用几种不同computeValue复杂性的方法执行许多计算.)

现在我需要Analyzer在运行时有选择地调整对象的行为(或者使用调整行为创建一个包装器).

我尝试了什么:

我添加了调整方法:

public Analyzer tweakAnalyzer(Analyzer untweakedAnalyzer) { ... }
Run Code Online (Sandbox Code Playgroud)

并尝试使用装饰器模式解决它:

class AnalyzerDecorator implements Analyzer {
    Analyzer delegate;
    public AnalyzerDecorator(Analyzer delegate) {
        this.delegate = delegate;
    }

    @Override
    public int computeValue() {
        return delegate.computeValue();
    }

    @Override
    public String performAnalysis() {
        return delegate.performAnalysis();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我实现tweakAnalyzer如下:

public Analyzer tweakAnalyzer(Analyzer untweakedAnalyzer) {
    return new AnalyzerDecorator(untweakedAnalyzer) {
        @Override
        public int computeValue() {
            return 1337;              // tweaked value!
        }
    };
}
Run Code Online (Sandbox Code Playgroud)

但是,在做的时候

tweakAnalyzer(new AnalyzerImpl()).performAnalysis();
Run Code Online (Sandbox Code Playgroud)

我得到了未被玷污的价值 Result: 5,而不是Result: 1337所希望的.

(这是因为调整后的分析器与未经过分析的分析器不是同一个对象,它只是一个包装器,因此对computeValuein 的调用AnalyzerImpl不能按预期工作.)

完整的ideone.com示例.

TL; DR:

我想在运行时调整对象的行为.我使用了装饰器模式,但"丢失"了所有虚拟方法.

题:

解决这个问题的最佳方法是什么,即我应该如何调整某个行为,Analyzer以便我不会松开虚拟方法查找,或者如果我这样做无关紧要?

Joa*_*son 5

问题是你的装饰器没有被调用,performAnalysis因为它不知道你装饰了类.

你或许应该打破performAnalysis,并computeValue分为两大类(AnalyzerperformAnalysisCalculatorcomputeValue)

这样,你可以独立装饰它们,并将装饰Analyzer好的计算器传递给' a' performAnalysis(Calculator calculator).

IDEOne的一个例子.是的,它基本上是战略模式.