代码重用的特征与抽象 类
Traits vs. abstract classes for code reuse
在处理一个项目时,我偶然发现了一个问题,该问题涉及根据特征与抽象基础 classes 选择正确的代码重用形式的正确方法。我发现我有多个抽象基础 classes 但由于 PHP 的多重继承限制只能继承一个。重新思考这让我质疑我的设计,所以我想知道其他人会如何解决这个问题。
以下场景
在我的项目中我有两种计算方式
- 简单计算
- 分组计算,以防万一是简单的计算,只是包含更多信息
设置接口
interface SimpleResultInterface{
public function getValue();
}
interface GroupedResultInterface extends SimpleResultInterface {
public function getGroupValues();
}
设置基础classes
避免代码重复是一种很好的设计形式,我设置了两个抽象基础classes。
abstract class SimpleResultBase implements SimpleResultInterface{
public function getValue(){
return 1;
}
}
abstract class GroupedResultBase extends SimpleResultBase implements GroupedResultInterface {
public function getGroupValues(){
return array(
"group1" => 1,
"group2" => 2,
"group3" => 3,
);
}
}
所以这里的第一个问题是
- GroupedResultBase从SimpleResultInterface表达接口关系是否需要继承SimpleResultBase和 GroupedResultInterface ?
我选择了是,否则我将不得不从 SimpleResultBase
复制 getValue 方法
我们目前有什么
现在我可以 epxpress
- GroupedResultInterface instanceof SimpleResultInterface ( true )
- GroupedResultBase instanceof SimpleResultBase ( true )
- SimpleResultBase instanceof SimpleResultInterface ( true )
- GroupedResultBase instanceof GroupedResultInterface ( true )
在问题开始的地方具体化
此时没有具体的 classes。现在我想制作两个具体的 classes,它们在接口定义方面有关系。
class OEESimpleResult extends SimpleResultBase {
}
class OEEGroupedResult extends GroupedResultBase{
}
这很好用,但我做不到的是这个
class OEESimpleResult extends SimpleResultBase {
}
class OEEGroupedResult extends OEESimpleResult,GroupedResultBase {
}
interface GroupedResultInterface extends SimpleResultInterface
As above noted in the interface definiton. Each grouped result is also
a simple result. So i would have expected that OEEGroupedResult also is a OEESimpleResult
但是当我这样做时,我不能重用我的抽象基础 class GroupedResultBase 因为不允许多重继承。这让我想到了以下问题。
- 抽象 classes 中的 class 关系似乎冻结了沿途的继承链。删除抽象的 classes 并将它们替换为使用它们的具体 classes 的特征会更好吗?
- 如果您有多个接口但只能从一个基础继承,那么提供默认实现的正确方法是什么class?
- 这个问题在 oop 中似乎很常见,那么有没有解决这个问题的最佳实践和建议?
- 实现接口的 classes 是否也应该像接口级别那样以继承的形式表达关系,或者仅接口关系就足够了吗?在我的例子中,OEEGroupedResult 应该在 class 级别上表达与 OEESimpleResult 的关系,就像它们在接口级别上的接口一样。
谢谢你的帮助:)
当您以 oop 风格工作时,您可能听说过 SOLID 原则。
因此,您的设计打破了以下字母 S、I、D,并有可能打破 O 和 L。
那你是怎么破解的"S":
就在这里!
class OEEGroupedResult extends OEESimpleResult,GroupedResultBase {
}
突然或幸运的是 php 不允许这样做,但是您的 class 会提供一些额外的独立逻辑,因此您至少有两个理由来更改它。但是,是的,这是因为
interface GroupedResultInterface extends SimpleResultInterface {
public function getGroupValues();
}
这是你的 I 字母中断。解决方案非常简单:考虑您的 GroupedResultInterface 真正需要的方法并将其放入其中 really 意味着这些方法必须完成相同的工作。他们不像你在这里打破字母 D:
abstract class SimpleResultBase implements SimpleResultInterface{
public function getValue(){
return 1;
}
}
abstract class GroupedResultBase extends SimpleResultBase implements GroupedResultInterface {
public function getGroupValues(){
return array(
"group1" => 1,
"group2" => 2,
"group3" => 3,
);
}
}
你的classclass GroupedResultBase
取决于另一个class的具体方法。但是你会在接口隔离之后很快修复它。
通知。当我无法更改 vendor classes 中的某些内容时,我正在使用特征。仅有的。这只是我,但当我认为这种特质会帮助我时,那么建筑就出了问题。这当然取决于你。
小link:https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)
玩得开心!
在处理一个项目时,我偶然发现了一个问题,该问题涉及根据特征与抽象基础 classes 选择正确的代码重用形式的正确方法。我发现我有多个抽象基础 classes 但由于 PHP 的多重继承限制只能继承一个。重新思考这让我质疑我的设计,所以我想知道其他人会如何解决这个问题。
以下场景
在我的项目中我有两种计算方式
- 简单计算
- 分组计算,以防万一是简单的计算,只是包含更多信息
设置接口
interface SimpleResultInterface{
public function getValue();
}
interface GroupedResultInterface extends SimpleResultInterface {
public function getGroupValues();
}
设置基础classes
避免代码重复是一种很好的设计形式,我设置了两个抽象基础classes。
abstract class SimpleResultBase implements SimpleResultInterface{
public function getValue(){
return 1;
}
}
abstract class GroupedResultBase extends SimpleResultBase implements GroupedResultInterface {
public function getGroupValues(){
return array(
"group1" => 1,
"group2" => 2,
"group3" => 3,
);
}
}
所以这里的第一个问题是
- GroupedResultBase从SimpleResultInterface表达接口关系是否需要继承SimpleResultBase和 GroupedResultInterface ?
我选择了是,否则我将不得不从 SimpleResultBase
复制 getValue 方法我们目前有什么
现在我可以 epxpress
- GroupedResultInterface instanceof SimpleResultInterface ( true )
- GroupedResultBase instanceof SimpleResultBase ( true )
- SimpleResultBase instanceof SimpleResultInterface ( true )
- GroupedResultBase instanceof GroupedResultInterface ( true )
在问题开始的地方具体化
此时没有具体的 classes。现在我想制作两个具体的 classes,它们在接口定义方面有关系。
class OEESimpleResult extends SimpleResultBase {
}
class OEEGroupedResult extends GroupedResultBase{
}
这很好用,但我做不到的是这个
class OEESimpleResult extends SimpleResultBase {
}
class OEEGroupedResult extends OEESimpleResult,GroupedResultBase {
}
interface GroupedResultInterface extends SimpleResultInterface
As above noted in the interface definiton. Each grouped result is also a simple result. So i would have expected that OEEGroupedResult also is a OEESimpleResult
但是当我这样做时,我不能重用我的抽象基础 class GroupedResultBase 因为不允许多重继承。这让我想到了以下问题。
- 抽象 classes 中的 class 关系似乎冻结了沿途的继承链。删除抽象的 classes 并将它们替换为使用它们的具体 classes 的特征会更好吗?
- 如果您有多个接口但只能从一个基础继承,那么提供默认实现的正确方法是什么class?
- 这个问题在 oop 中似乎很常见,那么有没有解决这个问题的最佳实践和建议?
- 实现接口的 classes 是否也应该像接口级别那样以继承的形式表达关系,或者仅接口关系就足够了吗?在我的例子中,OEEGroupedResult 应该在 class 级别上表达与 OEESimpleResult 的关系,就像它们在接口级别上的接口一样。
谢谢你的帮助:)
当您以 oop 风格工作时,您可能听说过 SOLID 原则。 因此,您的设计打破了以下字母 S、I、D,并有可能打破 O 和 L。
那你是怎么破解的"S": 就在这里!
class OEEGroupedResult extends OEESimpleResult,GroupedResultBase {
}
突然或幸运的是 php 不允许这样做,但是您的 class 会提供一些额外的独立逻辑,因此您至少有两个理由来更改它。但是,是的,这是因为
interface GroupedResultInterface extends SimpleResultInterface {
public function getGroupValues();
}
这是你的 I 字母中断。解决方案非常简单:考虑您的 GroupedResultInterface 真正需要的方法并将其放入其中 really 意味着这些方法必须完成相同的工作。他们不像你在这里打破字母 D:
abstract class SimpleResultBase implements SimpleResultInterface{
public function getValue(){
return 1;
}
}
abstract class GroupedResultBase extends SimpleResultBase implements GroupedResultInterface {
public function getGroupValues(){
return array(
"group1" => 1,
"group2" => 2,
"group3" => 3,
);
}
}
你的classclass GroupedResultBase
取决于另一个class的具体方法。但是你会在接口隔离之后很快修复它。
通知。当我无法更改 vendor classes 中的某些内容时,我正在使用特征。仅有的。这只是我,但当我认为这种特质会帮助我时,那么建筑就出了问题。这当然取决于你。
小link:https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)
玩得开心!