特征与代码重用的抽象类

时间:2016-08-23 11:44:11

标签: php oop interface class-hierarchy

在处理项目时,我偶然发现了一个问题,即在特征与抽象基类方面选择正确形式的代码重用的正确方法。我遇到了一个问题,我有多个抽象基类,但只能从PHP中继承一个多重继承限制。重新考虑这一点让我质疑我的设计,所以我想知道其他人如何解决这个问题。

以下方案

在我的项目中,我有两种计算

  1. 简单计算
  2. 分组计算,如果是简单的计算,只需要更多信息
  3. 设置界面

    interface SimpleResultInterface{
        public function getValue();
    }
    
    interface GroupedResultInterface extends SimpleResultInterface {
        public function getGroupValues();
    }
    

    设置基类

    避免代码重复作为一种良好的设计形式我设置了两个抽象基类。

    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,
            );
        }
    }
    

    所以这里的第一个问题是

    1. GroupedResultBase 是否需要继承 SimpleResultBase 来表达来自 SimpleResultInterface GroupedResultInterface 的接口关系?< / LI>

      我选择了是,否则我将不得不从 SimpleResultBase

      复制 getValue 方法

      到目前为止我们有什么

      现在我可以用epxpress

      1. GroupedResultInterface instanceof SimpleResultInterface (true)
      2. GroupedResultBase instanceof SimpleResultBase (true)
      3. SimpleResultBase instanceof SimpleResultInterface (true)
      4. GroupedResultBase instanceof GroupedResultInterface (true)
      5. 具体开始的地方

        此时没有具体的课程。现在我想制作两个具有关系的具体类,它们遵循界面定义。

        class OEESimpleResult extends SimpleResultBase {
        
        }
        
        class OEEGroupedResult extends GroupedResultBase{
        
        }
        

        这非常好用,但我不能做的就是这个

        class OEESimpleResult extends SimpleResultBase {
        
        }
        
        class OEEGroupedResult extends OEESimpleResult,GroupedResultBase {
        
        }
        
          

        interface GroupedResultInterface扩展SimpleResultInterface

             

        如上所述,界面定义。每个分组结果也是   一个简单的结果。所以我原本预计 OEEGroupedResult 也是 OEESimpleResult

        但是当我这样做时,我无法重用我的抽象基类 GroupedResultBase ,因为不允许多重继承。这导致我提出以下问题。

        1. 似乎抽象类中的类关系冻结了继承链。是否更好的是删除抽象类并用使用它们的具体类替换它们?
        2. 如果您有多个接口但只能从一个基类继承,那么提供默认实现的正确方法是什么?
        3. 这个问题在oop中似乎很常见,所以有没有最佳实践和建议如何克服这个问题?
        4. 实现接口的类是否也应该像接口级别一样以继承的形式表达关系,还是足够单独的接口实现?在我的情况下, OEEGroupedResult 应该在类级别上表达与 OEESimpleResult 的关系,就像它们在接口级别上的接口一样。
        5. 感谢您的帮助:)

1 个答案:

答案 0 :(得分:1)

当您使用oop风格时,您可能会听到有关SOLID原则的信息。 所以你的设计打破了以下字母S,I,D,有可能打破O和L.

那你怎么打破“S”: 就在这里!

class OEEGroupedResult extends OEESimpleResult,GroupedResultBase {

}

突然或幸运的是php不允许它,但是你的类会提供一些额外的独立逻辑,所以你至少有两个理由来改变它。但是,是因为

interface GroupedResultInterface extends SimpleResultInterface {
    public function getGroupValues();
}

这是你的信件中断。解决方案非常简单:考虑GroupedResultInterface真正需要的方法并将其放入其中,真正意味着这些方法必须完成相同的工作。它们并不像你在这里打破字母 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,
        );
    }
}

你的班级class GroupedResultBase取决于另一堂课的具体方法。但是在界面隔离后你会很快修复它。

<强>通知即可。当我无法在供应商类中更改某些内容时,我正在使用特征。只要。这只是我,但当我认为这种特性会帮助我时,那么建筑问题就出现了问题。当然,这取决于你。

小链接:https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)

玩得开心!