因此,我终于开始使用特征了,它们非常方便,我一直遇到的问题是我想拥有一些特征以向数据对象添加功能.
它本身很简单,除了使用我在基本数据对象中定义的方法来这样做
abstract class Base_Object {
protected function _addToUpdate($field, $value) {
...
}
...
}
trait Extended_Object {
public function doSomeStuff() {
...
$this->_addToUpdate($someVar, $someOtherVar);
}
...
}
class User extends Base_Object {
use Extended_Object;
...
}
然后我的问题是,如果团队中的其他人决定在不扩展Base_Object的对象上使用Extended_Object特性.我曾考虑过在_addToUpdate方法中进行检查,但理想情况下,我希望在创建实例时显示错误.
我想出了一个可行的解决方案,但使我感到有点脏,而且远非理想
abstract class Base_Object {
protected function _addToUpdate($field, $value) {
...
}
...
}
trait Extended_Object {
abstract protected function _addToUpdate($field, $value);
public function doSomeStuff() {
...
$this->_addToUpdate($someVar, $someOtherVar);
}
...
}
class User extends Base_Object {
use Extended_Object;
...
}
通过将一个抽象方法添加到Extended_Object中,我至少可以确定如果不存在我在Base_Object中需要的方法,则会显示一个错误,但是我不能保证所讨论的方法实际上会执行我想要的操作.
理想情况下,当我使用Extended_Object特性实例化对象时,我希望能够运行如下代码所示的内容
if (!($this instanceof Base_Object)) {
throw new Inheritance_Exception("Base_Object");
}
我希望有人找到了一种方法,或者至少比我的方法更好.
注意:我知道我可以使用构造函数来做到这一点,但是只有当我稍后决定创建其他对象扩展特征时,使用单个特征才能使它变得非常混乱
编辑:我确实意识到特质确实是为我想做的事情而设计的,但是它们至少部分地使我能够解决单一继承的问题,而且我知道我不是唯一计划以这种方式使用它们的开发人员
解决方法:
好吧(恕我直言)问题在于您使用特征的方式在技术上是anti-pattern.
首先,特征是什么,为什么要使用它们:
引用comments in php.net之一
The best way to understand what traits are and how to use them is to
look at them for what they essentially are: language assisted copy
and paste.If you can copy and paste the code from one class to another (and
we’ve all done this, even though we try not to because its code
duplication) then you have a candidate for a trait.
现在,即使有了这些特征,您也可以使用正在使用它们的类的成员,但这并不意味着您应该这样做.回到SRP,这是真正的违规.
PHP使您能够回显$_POST [‘XSS data’],但这并不意味着您应该这样做.因此,无论您要严格使用特质的方式如何,实际上是在引入问题并试图解决该问题.
因此,要回答您的问题,只需重新设计代码,以免您不使用类方法和成员,前提是假定将使用trait的每个类都应具有这些方法和成员.