如何避免在PHP

时间:2015-05-22 14:58:53

标签: php oop design-patterns

虽然这个问题是关于解决这个问题的方法,但我特别感兴趣的是干净的OO设计和符合当前PHP最佳实践的解决方案。提前谢谢你看看。

我有以下界面:

<?php

interface Tool {

  /**
   * Return the unique name of the tool
   */
  public function getName();

}

在我的项目中实现此接口的大多数类看起来像这样:

<?php

class Drill implements Tool {

    protected $toolName = 'drill';

    public function getName() {
        return $this->toolName;
    }

}

所以问题是我有几十个重复这个逻辑的类,复制$ toolName属性和getName()逻辑,打破了“不要重复自己”的简单规则

我考虑过的一个解决方案如下:

<?php

abstract class BaseTool implements Tool {

    public function getName() {
        return $this->toolName;
    }

}

然后只需要工具类扩展抽象BaseTool类:

<?php

class Drill extends BaseTool {

    protected $toolName = 'drill';
}

然而,现在这意味着如果扩展BaseTool类,我将失去强制实现类来定义函数getName()的能力,这会导致不正确的实现。

我还认为通过让BaseTool类返回$ this-&gt; toolName,它会对实现类进行假设并打破封装。

我使用了一个简单的例子来演示问题,但希望你能得到我想要解决的问题,而且这个问题也可能与更复杂的情况有关。欣赏你的想法。

3 个答案:

答案 0 :(得分:3)

如果您使用的是PHP 5.4.0+,请查看traits

您可以创建一个仅包含变量ToolInterfaceTrait

的getter / setter的$toolName

答案 1 :(得分:1)

你的尝试看起来不错。没什么好说的。

  

然而,现在这意味着如果扩展BaseTool类,我将失去强制实现类来定义函数getName()的能力,这会导致不正确的实现。

你仍然强迫他们,他们需要继承一个实现它们的类或者自己实现它们。

如果所有应该实现Tool的类都不可能从BaseTool扩展,请随意创建更多实现getName()的基类或直接实现它,如您所愿。

顺便说一句,如果您计划所有工具都应该扩展BaseTool,那么根本不需要接口,至少不是这个用例。接口用于并非所有用于实现它的类都从同一基类继承的情况。

答案 2 :(得分:0)

  

如何避免在PHP中重复实现的getter函数

抽象类通常用于对重复的代码进行分组。你走在正确的道路上。至于你对选择的怀疑......

  

然而,现在这意味着如果扩展BaseTool类,我将失去强制实现类来定义函数getName()的能力,这会导致不正确的实现。

通过扩展BaseTool类,类继承 getName()(这就是在抽象类中定义它的想法)。我不确定为什么会导致错误的实现,或者为什么你必须“强制实现类来定义它”。他们通过扩展抽象类来自动获取它。

  

我还认为通过让BaseTool类返回$ this-&gt; toolName,它会对实现类进行假设并打破封装。

如果在抽象类中定义toolName并在构造函数中设置其值可能会更清晰?

<?php

abstract class BaseTool implements Tool {

    protected $toolName;

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

    public function getName() {
        return $this->toolName;
    }

}

您可以在扩展类中定义构造函数以将其名称设置为:

<?php

class Drill extends BaseTool {

    public function __construct()
    {
        parent::__construct("drill");
    }

}