我一直在阅读这个“得墨忒耳法则”的东西,它(以及一般的纯“包装”类)似乎通常是反模式。考虑一个实现类:
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 除外)。
编辑:我遇到的许多真实例子之一,而不是一个微不足道的例子。