我知道抽象类可以有一个我们不想要的层次结构或树,所以我们使用trait更像是一次编写重复代码并包含在不同类中的方法。但是如果抽象类也没有层次结构呢?
如果我的课程只有一些可重用的逻辑,那么我们假设我们不需要多个特征。那么我们应该如何在这两者之间做出选择。
抽象类和特征中的方法都可以以相同的方式重写。简而言之,我们可以互相利用这两者。
例如:
class MyController{
use RestCrudTrait;
public function store(){
//override here
}
}
和
class MyController extends RestCrudController{
public function store(){
//override here
}
}
我试过它们,它们可以以这种方式互换使用。我也放在这里控制器,它可以是模型或其他东西。那么究竟需要如何选择使用Trait或扩展类。
如果由于这些层次结构等原因导致继承不好,那么在继承时可以随时使用Trait吗?
所以我想知道的是:
这两者是否只是逻辑上不同,实际上可以做同样的事情,可以互换使用吗?
即使它们在逻辑上不同,那么应该如何在这两者之间做出选择呢?
答案 0 :(得分:1)
我认为特质是一把严肃的双刃剑,一方面你可以像你说的那样复制代码,另一方面,你可以在这个过程中失去巨大的可读性。
在我看来,我只会使用traits进行简单的接口实现,比如一个只有getter和setter的ServiceManagerAwareInterface,以及一个特性ServiceManagerAwareTrait,它将进行实现以避免在每个实现我的类中编写getter和setter逻辑接口
以这种方式,它有助于使用接口隔离原则。
答案 1 :(得分:0)
如果我想重用代码,我实际上几乎总是选择继承或特性使用。虽然特征似乎是语言的一个很好的补充,但它们并不比在类本身内直接编写类new
的属性更好,而不是从外部注入。
在这两种情况下(即使用特征或扩展类时),在两个元素(特征的使用者或超类型的子元素)之间创建了非常紧密的耦合。
首先,您只能使用一种方法来构建对象图。
无论您做什么,MyController
都会直接与RestCrudTrait
或RestCrudController
相关联。
此外,这可能不是你的情况,有了traits和inheritance,你可能会使用你不希望类消耗特性或扩展父类的方法来对公共API进行策略。
无论如何,在大多数框架中,继承被深刻地使用(当自定义控制器扩展作为超类型的控件时),因为框架使用动态查找,如果可以访问路由或操作,则检查用户自制控制器的可用方法
在这样的场景中,我肯定会继承,因为你需要解决环境带来的约束。
如果您不限于任何约束,并且您想要的是简单的代码重用,而无需手动将组件注入到类中,并通过具有这些依赖关系的类的外观公开这些组件的方法,那么我会去对于一个特质。
尽管如此,我已经向我证明,你需要依赖一些代码,将它分配给私有变量并仅暴露你真正需要的代码,这通常是一个更好的主意,不仅仅是大多数用于测试(创建低耦合)。