【发布时间】:2010-03-31 06:47:01
【问题描述】:
我一直在阅读“得墨忒耳法则”这个东西,它(以及一般的纯“包装器”类)似乎通常是反模式。考虑一个实现类:
class FluidSimulator {
void reset() { /* ... */ }
}
现在考虑另一个类的两种不同实现:
class ScreenSpaceEffects1 {
private FluidSimulator _fluidDynamics;
public FluidSimulator getFluidSimulator() { return _fluidDynamics; }
}
class ScreenSpaceEffects2 {
private FluidSimulator _fluidDynamics;
public void resetFluidSimulation() { _fluidDynamics.reset(); }
}
以及调用上述方法的方法:
callingMethod() {
effects1.getFluidSimulator().reset(); // Version 1
effects2.resetFluidSimulation(); // Version 2
}
乍一看,版本 2 似乎更简单一些,并且遵循“Demeter 规则”,隐藏 Foo 的实现等。但这将 FluidSimulator 中的任何更改与 ScreenSpaceEffects 联系在一起。例如,如果一个参数被添加到reset,那么我们有:
class FluidSimulator {
void reset(bool recreateRenderTargets) { /* ... */ }
}
class ScreenSpaceEffects1 {
private FluidSimulator _fluidDynamics;
public FluidSimulator getFluidSimulator() { return _fluidDynamics; }
}
class ScreenSpaceEffects2 {
private FluidSimulator _fluidDynamics;
public void resetFluidSimulation(bool recreateRenderTargets) { _fluidDynamics.reset(recreateRenderTargets); }
}
callingMethod() {
effects1.getFluidSimulator().reset(false); // Version 1
effects2.resetFluidSimulation(false); // Version 2
}
在这两个版本中,callingMethod 都需要更改,但在版本 2 中,ScreenSpaceEffects 也需要更改。有人能解释一下使用包装器/外观的优势吗(适配器或包装外部 API 或暴露内部 API 除外)。
编辑:这是我遇到的许多真实示例之一,而不是一个微不足道的示例。
【问题讨论】:
-
你的意思是“版本 2 似乎更简单一些”?
-
是的,对不起,会改变
-
版本 1 不遵循得墨忒耳的规则。输入错误?
标签: design-patterns oop anti-patterns law-of-demeter