design-patterns - 包装器/得墨meter耳的法律似乎是一种反模式

标签 design-patterns oop anti-patterns law-of-demeter

我一直在阅读有关“Demeter法则”的文章,并且它(通常是纯“包装”类)似乎通常是反模式。考虑一个实现类:

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联系在一起。例如,如果添加了一个参数以进行重置,那么我们可以:
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除外)。

编辑:我遇到了许多实际示例,而不是琐碎的示例。

最佳答案

主要区别在于,在版本1中,作为Bar抽象的提供者,您无法控制Foo的公开方式。 Foo的任何更改都将向您的客户公开,他们将不得不接受。

在版本2中,作为抽象Bar的提供者,您可以决定是否以及如何公开演变。它仅取决于Bar的抽象,而不取决于Foo的抽象。在您的示例中,您的Bar抽象可能已经知道要作为参数传递哪个整数,因此您将能够让您的用户透明地使用新版本的Foo,而无需进行任何更改。

假设现在Foo不断发展,并且要求用户先调用foo.init(),然后再调用doSomething。在版本1中,Bar的所有用户都将需要查看Foo的更改,并修改其代码。对于版本2,只需更改Bar,如果需要,其doSomething会调用init。这导致更少的错误(仅抽象Bar的作者必须了解和理解抽象Foo并减少了类之间的耦合。

关于design-patterns - 包装器/得墨meter耳的法律似乎是一种反模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2550961/

相关文章:

c++ - 多重继承 : calling all the overriden functions

Java Restful Web 服务 (jax rs) 身份验证模式

c# - 为什么我们需要观察者模式?

javascript - MooTools 1.3+ 类中的私有(private)属性

perl - 使用Scalar::Util 的弱化会导致无效引用问题吗?

design-patterns - 全局常量是反模式吗?

design-patterns - XML 序列化很慢

php - 有什么方法可以在 PHP 中安全地重新声明一个类?

oop - 什么是界面膨胀?

java - 像包装器一样使用 Facade