【问题标题】:Is there a common name for this code smell?这种代码气味有一个通用名称吗?
【发布时间】:2012-10-09 10:10:06
【问题描述】:

我称它为“送货员”。我已经看到了它的几个变体,但问题是一个类具有依赖项,其唯一目的是将它传递给协作者并且从不使用依赖项本身。

(我使用 PHP 是因为它是我最熟悉的,但它与语言无关)

class Dependency{}

class B {
    public function setDependency(Dependency $dependency) {
        //...
    }
}

class A {
    private $b;
    private $dependency;

    public function __construct(Dependency $dependency, B $b) {
        $this->dependency = $dependency;
        $this->b = $b;
    }

    public function foo() {
        $this->b->setDependency($this->dependency);
    }
}

可能我在野外看到的最常见的变体是为此目的滥用继承,在父类中拥有一个存在的属性,以便子类可以访问依赖项,即使父类从未实际使用依赖项本身.

class Dependency{}



class A {
    protected $dependency;

    public function __construct(Dependency $dependency) {
        $this->dependency = $dependency;
    }
}

class B extends A {
    public function foo() {
        $this->dependency->bar();
    }
}

我在代码中看到的比我想要的要多得多,这让我很不高兴!我只是想知道是否有一个名称,以便我可以将人们链接到阅读材料,了解为什么这是一个坏主意。就目前而言,我不知道要搜索什么!

【问题讨论】:

    标签: oop dependencies anti-patterns


    【解决方案1】:

    我不知道任何名字,但我有点喜欢送货员......虽然我想有些人可能会认为这个名字有点冒犯。

    通常这个问题可以通过依赖注入或服务定位器来解决,尽管太多人使用单例来解决这个问题(不恰当地)。

    我对 PHP 不够熟悉,不知道 PHP 是否提供真正的 DI 解决方案(与穷人的 DI 不同),但我认为如果没有,服务定位器是可以接受的(即使服务定位器经常本身就是一种代码味道)。

    【讨论】:

    • 正如你所写,ServiceLocator 是“更好的Singleton”; type 压力太大,而不是 object。 OP的用法似乎对实际对象至少有同样的压力,不知道如何使用ServiceLocator代替。
    • @MiserableVariable - 在许多情况下,您不需要特定的实例,但是依赖注入框架通常具有配置它是否使用现有实例、新实例或池实例的方法,管他呢。服务定位器当然可以做同样的事情。尽管如此,DI 和 SL 并不是解决这个问题的唯一方法,但它们很常见。
    • 如果您考虑许多不需要特定实例的情况,我们可能会讨论两个不同的问题。对我来说,这里的依赖是在对象级别而不是类型级别。
    • @MiserableVariable - 您不需要特定实例的情况通常围绕单元测试展开,您将实现作为依赖项传递给其他对象以抽象功能。另一种情况是您使用工厂返回特定实例。数据本身可能是特定的,但工厂不是。
    • 谢谢,但我不得不承认我不知道你为什么要向我解释我不需要特定实例的情况:)
    【解决方案2】:

    第二个 sn-p 中与继承相关的问题在我看来就像“Broken Hierarchy”。当基类和它的派生类不共享 IS-A 关系时,就会出现这种气味。发现代码使用继承只是为了方便(为了重用)而不是因为参与的类相关(通过 IS-A 关系)的层次结构是很常见的。

    (我借用了"Refactoring for software design smells"一书中的气味术语(即Broken Hierarchy))

    【讨论】:

      猜你喜欢
      • 2010-09-09
      • 2020-06-28
      • 2011-01-27
      • 1970-01-01
      • 2011-01-14
      • 2021-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多