设计模式-超级反模式调用-避免或保持

zoz*_*ozo 5 php design-patterns anti-patterns

我最近注意到,在某些情况下,我实际上喜欢做的事情(称为super)是一种反模式。(http://en.wikipedia.org/wiki/Call_super

所以我的问题是:

如何执行以下操作(我们大多数人都需要的基本操作,请向对象添加一些细节)。我将添加一个新元素到保存在对象var中的数组中:

   <?php
   class A {
       // bla bla bla
       public function __construct() {
            $this->_data['newDetail'] = "Ipiicaei";
       }
   }


   class B extends A {
       // bla bla bla
       // Override constructor, I need to add one more detail for this class
       public function __construct() {
            parent::__construct();
            $this->_data['newDetailSubcls'] = "Something";
       }
   }
Run Code Online (Sandbox Code Playgroud)

现在...如果不调用父类构造函数来添加第一个元素,则有两种可能性:

  1. 在每个子类中,添加父级通常要做的部分代码,并将其从父级中删除。因此,如果我将其扩展为999个类,则会在父级中复制999 *行。听起来对我不好。

  2. 从父级中调用在子级中实现的方法(模板方法模式,他们推荐的方法)。因此,如果我只需要添加一个类,而998的其余部分的行为与父类完全相同,则在每个类中我都添加一个空函数。这对我来说听起来也很糟糕。

请记住,我的示例很简单(示例应该就是这样),但是父类和/或子类可能会做复杂的事情。

我可以看到为什么在某些情况下调用super可能不好的原因。但是在我看来这还可以。

那么...您将如何处理?忽略call super是一种反模式,并且按我的方式做(或者如果事实证明我的方法不好,就可以这样做)?还是……怎么了?

rae*_*ae1 4

使用构造函数是这种反模式如何出现的一个坏例子,因为在 PHP 中,就像大多数支持继承的语言一样,

如果子类没有定义构造函数,那么它可以像普通的类方法一样从父类继承......(来自PHP 手册)。

如果在任何其他 998 个类中,您试图定义故意不包含构造函数,则将调用基本构造函数,因此几乎需要在每个派生类上添加构造函数以避免此功能。这就是为什么不建议在构造函数中添加可能改变受保护字段/属性的状态的逻辑,或调用可能在派生类中重写的虚拟方法。

然而,反模式实际上表达的是:

请注意,调用父级的要求是反模式(来自维基百科

因此,只要派生类不需要这样做,就可以调用方法的基类版本。即使从未调用基方法,派生类也必须正确运行。这将避免派生类重写虚拟方法但未实现某些特殊要求(可能是因为基类缺乏文档)的情况,此时派生类的行为不符合系统的预期,可能导致系统崩溃或表现异常,典型地违反了里氏替换原则

在您的特定示例中,这种反模式不适用:您正在扩展构造函数,根据定义,在将类实例化为有用状态时需要调用构造函数。在大多数情况下,这就是您想要的。